home *** CD-ROM | disk | FTP | other *** search
- /* ---------------------------------------------------------------------- */
- /* LADYBUG */
- /* */
- /* Copyrighted 1994-1995 by Long Doan, ld@netrix.com */
- /* ---------------------------------------------------------------------- */
-
- /* This debugger was derived from:
-
- SALLY FULL SCREEN DEBUGGER
- version 0.91a
- by
- Morten Welinder, terra@diku.dk
-
- This debugger is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This debugger is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with djgpp; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
- /* ---------------------------------------------------------------------- */
- #define LADYBUG_VERSION 1.02
- #define MAJOR_VER 1
- #define MINOR_VER 02
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <ctype.h>
- #include <pc.h>
- #include <dos.h>
- #include <go32.h>
- #include <dpmi.h>
- #include <keys.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <setjmp.h>
- #define far
- #include "ed.h"
- #include "debug.h"
- #include "syms.h"
- #include "paging.h"
- #include "unassmbl.h"
- #include "npx.h"
- #include "serial.h"
- #include "fsfuncts.h"
- #include "xsupport.h"
- #include "perform.h"
- #include "io.h"
-
- /* END_OF_INCLUDES */
- /* ----------------------------------------------------------------------
- - Information about the initialization state of the debugger. Actually
- - I'm not sure that longjmp should ever be permitted.
- ---------------------------------------------------------------------- */
- int can_longjmp = 0;
- jmp_buf debugger_jmpbuf;
- /* ----------------------------------------------------------------------
- - Information added to use com port - by Long Doan
- ---------------------------------------------------------------------- */
- static int using_com_port_num;
- int is_in_running_mode = 0;
- /* ----------------------------------------------------------------------
- - Display information.
- ---------------------------------------------------------------------- */
- int debug_screen_p;
- int toplines, bottomlines;
- int main_x1, main_x2, main_x3;
- /* ----------------------------------------------------------------------
- - Information about panes.
- ---------------------------------------------------------------------- */
- #define PANECOUNT 11
- #define CODE_PANE_NUM 0
- #define REGISTER_PANE_NUM 1
- #define FLAG_PANE_NUM 2
- #define BREAKPOINT_PANE_NUM 3
- #define DATA_PANE_NUM 4
- #define NPX_PANE_NUM 5
- #define STACK_PANE_NUM 6
- #define INFO_PANE_NUM 7
- #define WHEREIS_PANE_NUM 8
- #define MODULE_PANE_NUM 9
- #define HELP_PANE_NUM 10
- static int pane, pane_positions[PANECOUNT], pane_pos;
- static int pane_offset[PANECOUNT];
- static word32 data_dump_origin, data_dump_last, data_dump_size;
- static word32 code_dump_origin, code_dump_last;
- static word32 *code_pane_pos, *stack_dump_pos;
- static int stack_dump_origin, stack_dump_last, stack_dump_more;
- static int breakpoint_origin;
- static word32 *whereis_pane_sym;
- static char **module_pane_text;
- static char **help_pane_text;
- static int whereis_sym_count, whereis_origin;
- static int module_text_count, module_origin;
- static int help_text_count, help_origin;
- static int reg_pane_origin, flag_pane_origin;
- static int code_pane_active;
- static int npx_pane_active;
- static int stack_pane_active;
- static int info_pane_active;
- static int whereis_pane_active;
- static int module_pane_active;
- static int help_pane_active;
- static int running_xsupport = 0;
- static char active_pane_name[20];
- /* ----------------------------------------------------------------------
- - Menus
- ---------------------------------------------------------------------- */
- static MENU_ITEM File_Sub_Menu[] = {
- {"Current item ", 1 , "" , 0},
- {"Read/write log ~^X^F~", ITEM_TYPE, "\030\006" , 0},
- {"View debug registers ", ITEM_TYPE, "" , 0},
- {"Resize Screen ", ITEM_TYPE, "" , 0},
- {"Monochrome Mode ~^X m~", ITEM_TYPE, "\030m" , 0},
- {"Color Mode ", ITEM_TYPE, "" , 0},
- {"Redirect IO ", ITEM_TYPE, "" , 0},
- {"Save/load context ~^X^V~", ITEM_TYPE, "\030\026" , 0},
- {"Exit ~^X^C~", ITEM_TYPE, "\030\003" , 0},
- {0 , 0 , "" , 0}
- };
- static MENU_ITEM Pane_Sub_Menu[] = {
- {"Current ", 1 , "" , 0},
- {"~P~revious ", ITEM_TYPE, "p", 0},
- {"~N~ext ", ITEM_TYPE, "n", 0},
- {"~B~reakpoint", ITEM_TYPE, "b", 0},
- {"~C~ode ", ITEM_TYPE, "c", 0},
- {"~D~ata ", ITEM_TYPE, "d", 0},
- {"~F~lags ", ITEM_TYPE, "f", 0},
- {"~H~elp ", ITEM_TYPE, "h", 0},
- {"~I~nfo ", ITEM_TYPE, "i", 0},
- {"~M~odule ", ITEM_TYPE, "m", 0},
- {"Np~X~ ", ITEM_TYPE, "x", 0},
- {"~R~egisters ", ITEM_TYPE, "r", 0},
- {"~S~tack ", ITEM_TYPE, "s", 0},
- {"~W~here-is ", ITEM_TYPE, "w", 0},
- {"Resi~Z~e ", ITEM_TYPE, "z", 0},
- {0 , 0 , "" , 0}
- };
- static MENU_ITEM Help_Sub_Menu[] = {
- {"Current ", 1 , "" , 0},
- {"~A~bout ", ITEM_TYPE, "a", 0},
- {"~H~elp ", ITEM_TYPE, "h", 0},
- {0 , 0 , "" , 0}
- };
- static MENU_ITEM Misc_Sub_Menu[] = {
- {"Current ", 1 , "" , 0},
- {"~U~ser screen", ITEM_TYPE, "u", 0},
- {"~E~valuate ", ITEM_TYPE, "e", 0},
- {"~R~efresh ", ITEM_TYPE, "r", 0},
- {0 , 0 , "" , 0}
- };
- static MENU_ITEM Main_Menu[] = {
- {"Current " , 1 , "" , 0 },
- {"~F~ile " , MENU_TYPE, "f", File_Sub_Menu},
- {"~P~ane " , MENU_TYPE, "p", Pane_Sub_Menu},
- {"~L~ocal menu ", ITEM_TYPE, "l", 0 },
- {"~M~isc " , MENU_TYPE, "m", Misc_Sub_Menu},
- {"~H~elp " , MENU_TYPE, "h", Help_Sub_Menu},
- {0 , 0 , "" , 0 }
- };
- /* ----------------------------------------------------------------------
- - Odds and ends.
- ---------------------------------------------------------------------- */
- #define MAXINSTLEN 16
- static int first_step;
- static int escaped, control_c, control_x;
- static word32 main_entry;
- static int has_npx = 1;
- NPX npx; /* non-static because declared so in "npx.h" */
- static char hexchars[] = "0123456789abcdef";
- #define MAX_REGISTERS 75
- #define SCROLL_COUNT 5
- #define ACTION_HIST_SIZE 40
- static word32 registers[MAX_REGISTERS];
- static char last_addr[4096];
- /* ----------------------------------------------------------------------
- - The presentation order of registers in the register pane. The three
- - tables must of course match.
- ---------------------------------------------------------------------- */
- static char *regs_names[] = {
- "eax", "ebx", "ecx", "edx", "esi", "edi", "ebp", "esp",
- "cs", "ds", "es", "fs", "gs", "ss",
- "eip", "flg" };
- static word32 *regs_addr[] = {
- &a_tss.tss_eax, &a_tss.tss_ebx, &a_tss.tss_ecx, &a_tss.tss_edx,
- &a_tss.tss_esi, &a_tss.tss_edi, &a_tss.tss_ebp, &a_tss.tss_esp,
- (word32 *)&a_tss.tss_cs, (word32 *)&a_tss.tss_ds,
- (word32 *)&a_tss.tss_es, (word32 *)&a_tss.tss_fs,
- (word32 *)&a_tss.tss_gs, (word32 *)&a_tss.tss_ss,
- &a_tss.tss_eip, &a_tss.tss_eflags };
- /* ----------------------------------------------------------------------
- - g: general, !: special, s: segment, f: flags, \0: end-of-table
- ---------------------------------------------------------------------- */
- static char regs_type[] = "ggggggg!ssssss!f";
- /* ----------------------------------------------------------------------
- - Breakpoint data. When breakpoints are actually put into the cpu debug
- - registers, data breakpoints have first priority. Any code breakpoints
- - left over are set by patching the code to contain "Int 3".
- ---------------------------------------------------------------------- */
- typedef enum { BP_Code = 0, BP_Write = 1, BP_Read = 3 } BP_TYPE;
- typedef enum { BP_Normal = 0, BP_Count = 1, BP_Condition = 2 } BP_SUB_TYPE;
-
- typedef struct
- {
- word32 addr;
- BP_TYPE type;
- BP_SUB_TYPE sub_type;
- int count;
- char condition[200];
- unsigned char length; /* 1, 2, or 4 bytes */
- unsigned char saved;
- unsigned char savedbyte; /* Patched-away byte. */
- } BP_ENTRY;
-
- static int breakpoint_count;
- static BP_ENTRY *breakpoint_table;
- static unsigned char int03 = 0xcc;
-
- #define MAX_UNDO 5
- typedef struct undo_data {
- word32 addr;
- word32 value;
- int size;
- } UNDO_DATA;
- typedef struct {
- struct undo_data data[MAX_UNDO];
- int count;
- void (*free_entry)(word32);
- } UNDO_STRUCT;
- static UNDO_STRUCT data_undo;
- static UNDO_STRUCT register_undo;
- static UNDO_STRUCT breakpoint_undo;
- static UNDO_STRUCT npx_undo;
- /* ---------------------------------------------------------------------- */
- static void
- test_npx (void)
- { asm ("push %eax \n\
- push %ebx \n\
- movl %cr0, %eax \n\
- andl $0x04, %eax \n\
- jnz Has_387 \n\
- clts \n\
- fninit \n\
- movl $_npx, %eax \n\
- movl $0x5a5ah, (%eax)\n\
- fnstsw (%eax) \n\
- cmpb $0, (%eax) \n\
- jne No_387 \n\
- fnstcw (%eax) \n\
- movw (%eax), %bx \n\
- and $0x103f, %bx \n\
- cmpw $0x3f, %bx \n\
- jne No_387 \n\
- fld1 \n\
- fldz \n\
- fdiv \n\
- fld %st \n\
- fchs \n\
- fcompp \n\
- fstsw (%eax) \n\
- movw (%eax), %bx \n\
- sahf \n\
- je No_387 \n\
- Has_387: \n\
- movl $1, _has_npx \n\
- jmp Test_done \n\
- No_387: \n\
- movl $0, _has_npx \n\
- Test_done: \n\
- pop %ebx \n\
- pop %eax "
- );
- }
- /* ---------------------------------------------------------------------- */
- static void
- save_npx (void)
- {
- asm( "\n\
- inb $0xa0,%al \n\
- testb $0x20,%al \n\
- jz Lfclex_done \n\
- xorl %eax,%eax \n\
- outb %al,$0xf0 \n\
- movb $0x20,%al \n\
- outb %al,$0xa0 \n\
- outb %al,$0x20 \n\
- Lfclex_done: \n\
- movl $_npx, %eax \n\
- fnsave (%eax) \n\
- fwait "
- );
- }
- /* ---------------------------------------------------------------------- */
- static void
- load_npx (void)
- {
- asm( "\n\
- movl $_npx, %eax \n\
- frstor (%eax) "
- );
- /* After line 1 */
- /* movb $0,4(%eax) */
- /* clear pending exceptions */
- /* At least on my 486 there is no need to clear pending exceptions. */
- }
- /* ---------------------------------------------------------------------- */
- /* Display the debugger screen (if not already displayed). */
- static void
- debug_screen (void)
- { if (!debug_screen_p)
- {
- user_screen_save = get_screen ();
- if (using_com_port_num)
- screen_scroll (rows);
- put_screen (debug_screen_save);
- debug_screen_p = 1;
- }
- }
- /* ---------------------------------------------------------------------- */
- /* Display the user screen (if not already displayed). */
- static void
- user_screen (void)
- { if (debug_screen_p)
- {
- if (using_com_port_num)
- screen_scroll (rows);
- else
- put_screen (user_screen_save);
- free (user_screen_save);
- debug_screen_p = 0;
- }
- }
- /* ---------------------------------------------------------------------- */
- static void
- free_do_nothing (word32 addr)
- {
- }
- /* ---------------------------------------------------------------------- */
- static void
- free_breakpoint (word32 addr)
- { BP_ENTRY *bp_to_free = (BP_ENTRY *)addr;
- free (bp_to_free);
- }
- /* ---------------------------------------------------------------------- */
- static void
- free_npx (word32 addr)
- { NPX *npx_to_free = (NPX *)addr;
- free (npx_to_free);
- }
- /* ---------------------------------------------------------------------- */
- static void
- init_undo (UNDO_STRUCT *what_undo, void (*free_func)(word32))
- { what_undo->count = 0;
- what_undo->free_entry = free_func;
- }
- /* ---------------------------------------------------------------------- */
- static void
- reinit_undo (UNDO_STRUCT *what_undo)
- { while (what_undo->count)
- { what_undo->count--;
- what_undo->free_entry (what_undo->data[what_undo->count].value);
- }
- }
- /* ---------------------------------------------------------------------- */
- static void
- put_undo (UNDO_STRUCT *what_undo, word32 addr, word32 val, int size)
- { if (what_undo->count == MAX_UNDO)
- { int i;
- what_undo->free_entry (what_undo->data[0].value);
- for (i = 1; i < what_undo->count; i++)
- { what_undo->data[i - 1].addr = what_undo->data[i].addr;
- what_undo->data[i - 1].value = what_undo->data[i].value;
- what_undo->data[i - 1].size = what_undo->data[i].size;
- }
- what_undo->count--;
- }
- what_undo->data[what_undo->count].addr = addr;
- what_undo->data[what_undo->count].value = val;
- what_undo->data[what_undo->count].size = size;
- what_undo->count++;
- }
- /* ---------------------------------------------------------------------- */
- static int
- get_undo (UNDO_STRUCT *what_undo, word32 *addr, word32 *val, int *size)
- { if (what_undo->count <= 0)
- return (0);
- what_undo->count--;
- *addr = what_undo->data[what_undo->count].addr;
- *val = what_undo->data[what_undo->count].value;
- *size = what_undo->data[what_undo->count].size;
- return (1);
- }
- /* ---------------------------------------------------------------------- */
- typedef enum { not, com, mul, divi, add, sub, shl, shr,
- and, xor, or, land, lor, less, greater, not_equal,
- less_equal, great_equal, equal} OPR_Name;
- typedef struct {
- char *str;
- OPR_Name name;
- } OPR_TYPE;
- typedef struct {
- OPR_TYPE *opers;
- int opers_num;
- } OPR_CLASS;
-
- static OPR_TYPE opers0[] = { /* Lowest priority first */
- {"||", lor },
- {"&&", land },
- {0 , 0 }
- };
- static OPR_TYPE opers1[] = {
- {"==", equal },
- {">=", great_equal},
- {"<=", less_equal },
- {"!=", not_equal },
- {">" , greater },
- {"<" , less },
- {0 , 0 }
- };
- static OPR_TYPE opers2[] = {
- {"|" , or },
- {"^" , xor },
- {"&" , and },
- {0 , 0 }
- };
- static OPR_TYPE opers3[] = {
- {">>", shr },
- {"<<", shl },
- {0 , 0 }
- };
- static OPR_TYPE opers4[] = {
- {"-" , sub },
- {"+" , add },
- {0 , 0 }
- };
- static OPR_TYPE opers5[] = {
- {"/" , divi },
- {"*" , mul },
- {0 , 0 }
- };
- static OPR_TYPE opers6[] = { /* Unary, left until the end. */
- {"~" , com },
- {"!" , not },
- {0 ,0 }
- };
- static OPR_CLASS operators[] = {
- {opers0, 2 },
- {opers1, 6 },
- {opers2, 3 },
- {opers3, 2 },
- {opers4, 2 },
- {opers5, 2 },
- {opers6, 2 },
- {0 , 0 }
- };
- static char l_str[200], r_str[200];
- /* ---------------------------------------------------------------------- */
- static char *
- i_strstr (char *s1, char *s2)
- { int i, len1, len2;
- if (!s1 || !s2)
- return (0);
- len1 = strlen (s1);
- len2 = strlen (s2);
- if (!len2)
- return (s1);
- if (!len1 || len1 < len2)
- return (0);
- for (i = len1 - len2; i >= 0; i--)
- if (strncmp (s1 + i, s2, len2) == 0)
- return (s1 + i);
- return (0);
- }
- /* ---------------------------------------------------------------------- */
- static void
- break_up (char *expr, OPR_Name *opr_num, int *found)
- { word32 pos, maxpos;
- int i, j, k = 1, len = strlen(expr);
- char *ptr = 0, *testptr = 0;
-
- l_str[0] = '\0';
- r_str[0] = '\0';
- *found = 0;
- for (i = 0; !(*found) && operators[i].opers; i++)
- { maxpos = 0;
- k = 0;
- for (j = 0; j < operators[i].opers_num; j++)
- { testptr = i_strstr(expr, operators[i].opers[j].str);
- pos = (word32)testptr;
- if (pos)
- { pos -= (word32)expr;
- if (pos > maxpos)
- { maxpos = pos;
- ptr = testptr;
- k = j;
- }
- *found = 1;
- }
- }
- }
- if (*found)
- { i--;
- len -= strlen (ptr);
- if (len > 0)
- strncpy(l_str, expr, len);
- l_str[len] = 0;
- len = strlen (l_str) - 1;
- while (len >= 0 && l_str[len] == ' ')
- l_str[len--] = 0;
- ptr++;
- *opr_num = operators[i].opers[k].name;
- switch (*opr_num)
- {
- case shl:
- case shr:
- case land:
- case lor:
- case not_equal:
- case less_equal:
- case great_equal:
- case equal:
- ptr++;
- break;
- default:
- break;
- }
- while (*ptr && *ptr == ' ')
- ptr++;
- strcpy(r_str, ptr);
- }
- }
- /* ---------------------------------------------------------------------- */
- static long
- parse_expression_without_paren (int size, char *expr, int *okp)
- {
- long l_val, r_val, result = 0;
- char *l_expr, *r_expr;
- OPR_Name opr_num;
- int found;
-
- break_up(expr, &opr_num, &found);
- if (found)
- { if (opr_num == divi && expr[0] == '/')
- { result = syms_name2val(expr);
- if (undefined_symbol)
- { *okp = ParseError_undef;
- return 0;
- }
- *okp = ParseError_ok;
- } else
- { l_expr = strdup(l_str);
- r_expr = strdup(r_str);
- r_val = parse_expression_without_paren (size, r_expr, okp);
- free (r_expr);
- if (*okp != ParseError_ok)
- { free (l_expr);
- return 0;
- }
- l_val = parse_expression_without_paren (size, l_expr, okp);
- free (l_expr);
- if (*okp != ParseError_ok)
- return 0;
- *okp = ParseError_ok;
- switch (opr_num)
- { case not:
- result = !r_val;
- break;
- case com:
- result = ~r_val;
- break;
- case mul:
- result = l_val * r_val;
- break;
- case divi:
- if (r_val == 0)
- { *okp = ParseError_divzero;
- return 0;
- } else
- result = l_val / r_val;
- break;
- case add:
- result = l_val + r_val;
- break;
- case sub:
- result = l_val - r_val;
- break;
- case shl:
- result = l_val << r_val;
- break;
- case shr:
- result = l_val >> r_val;
- break;
- case and:
- result = l_val & r_val;
- break;
- case xor:
- result = l_val ^ r_val;
- break;
- case or :
- result = l_val | r_val;
- break;
- case land:
- result = l_val && r_val;
- break;
- case lor:
- result = l_val || r_val;
- break;
- case equal:
- result = (l_val == r_val);
- break;
- case great_equal:
- result = (l_val >= r_val);
- break;
- case less_equal:
- result = (l_val <= r_val);
- break;
- case not_equal:
- result = (l_val != r_val);
- break;
- case greater:
- result = (l_val > r_val);
- break;
- case less:
- result = (l_val < r_val);
- break;
- }
- }
- } else
- { result = syms_name2val(expr);
- if (undefined_symbol)
- {
- *okp = ParseError_undef;
- return 0;
- }
- *okp = ParseError_ok;
- }
- switch (size)
- { case 1:
- return (short)(result & 0xff);
- case 2:
- return (int)(result & 0xffff);
- case 4: /* Fall through */
- default:
- return result;
- }
- }
- /* ---------------------------------------------------------------------- */
- long
- parse_expression (int size, char *expr, int *okp)
- { int len = strlen (expr);
- char *new_exp1 = alloca (len * 2 + 10), *new_exp2 = alloca (len * 2 + 10);
- int left_paren = 0, right_paren = 0, i, found = 1;
- char lookfor = ']';
- long temp_value;
-
- *okp = ParseError_ok;
- strcpy (new_exp1, expr);
- while (found)
- { for (i = 0; (i < len) && (new_exp1[i] != lookfor); i++)
- ;
- if (i == len)
- i = len - 1;
- if (new_exp1[i] != lookfor)
- { if (lookfor == ']')
- lookfor = ')';
- else
- found = 0;
- } else
- { right_paren = i;
- if (lookfor == ']')
- lookfor = '[';
- else
- lookfor = '(';
- for (i = right_paren - 1; (i >= 0) && (new_exp1[i] != lookfor); i--)
- ;
- if (i < 0)
- i = 0;
- if (new_exp1[i] != lookfor)
- { *okp = ParseError_paren;
- return (0);
- }
- left_paren = i;
- temp_value = 0;
- for (i = left_paren + 1; (i < right_paren); i++, temp_value++)
- new_exp2[temp_value] = new_exp1[i];
- new_exp2[temp_value] = 0;
- temp_value = parse_expression (size, new_exp2, okp);
- if (*okp != ParseError_ok)
- return (0);
- if (lookfor == '[')
- { switch (new_exp1[++right_paren])
- { case 'b':
- i = 1;
- break;
- case 'h':
- i = 2;
- break;
- case 'f':
- i = 4;
- break;
- default:
- i = 4;
- right_paren--;
- break;
- }
- if (valid_addr (temp_value, i))
- read_child (temp_value, &temp_value, i);
- else
- { *okp = ParseError_addr;
- return (0);
- }
- switch (i)
- { case 1:
- temp_value &= 0x000000ff;
- break;
- case 2:
- temp_value &= 0x0000ffff;
- break;
- }
- }
-
- strncpy(l_str, new_exp1, left_paren);
- strcpy(r_str, new_exp1 + right_paren + 1);
- l_str[left_paren] = 0;
- r_str[len - right_paren + 1] = 0;
- sprintf (new_exp2, "%s0x%08lx%s", l_str, temp_value, r_str);
- strcpy (new_exp1, new_exp2);
- len = strlen (new_exp1);
-
- if (lookfor == '[')
- lookfor = ']';
- else
- lookfor = ')';
- }
- }
- return (parse_expression_without_paren (size, new_exp1, okp));
- }
- /* ---------------------------------------------------------------------- */
- static long
- read_eval (int *okp, char *starttext)
- {
- long result;
-
- *okp = !read_string (starttext);
- if (*okp && read_buffer[0] != '\0')
- {
- result = parse_expression (4, read_buffer, okp);
- if (*okp == ParseError_ok)
- { *okp = 1;
- return (result);
- }
- switch (*okp)
- { case ParseError_addr:
- message (CL_Error, "Reference to an invalid address.");
- break;
- case ParseError_divzero:
- message (CL_Error, "Divide by zero.");
- break;
- case ParseError_paren:
- message (CL_Error, "Unbalanced [] or ().");
- break;
- case ParseError_syntax:
- message (CL_Error, "Syntax error.");
- break;
- case ParseError_undef:
- message (CL_Error, "Undefined symbol.");
- break;
- }
- *okp = 0;
- return (0);
- }
- else
- return *okp = 0;
- }
- /* ---------------------------------------------------------------------- */
- inline static int
- valid_instaddr (word32 vaddr)
- {
- return valid_addr (vaddr, MAXINSTLEN);
- }
- /* ---------------------------------------------------------------------- */
- /* Set physical breakpoint registers from virtual ones. */
- static void
- activate_breakpoints (void)
- {
- int b, no;
- BP_ENTRY *bep;
-
- no = 0;
- edi.dr[7] = 0;
- /* First handle data breakpoints. */
- for (b = 0, bep = breakpoint_table; b < breakpoint_count; b++, bep++)
- if (no <= 3 && bep->type != BP_Code)
- {
- bep->saved = 0;
- edi.dr[7] |= ((bep->type + ((bep->length - 1) << 2)) << (16 + 4 * no)
- | (2 << (2 * no)));
- edi.dr[no] = bep->addr + edi.app_base;
- no++;
- }
-
- /* Now handle code breakpoint. */
- for (b = 0, bep = breakpoint_table; b < breakpoint_count; b++, bep++)
- if (bep->type == BP_Code)
- if (no <= 3)
- {
- bep->saved = 0;
- edi.dr[7] |= ((BP_Code << (16 + 4 * no)) | (2 << (2 * no)));
- edi.dr[no] = bep->addr + edi.app_base;
- no++;
- edi.dr[7] |= 0x00000300L; /* For 386s we set GE & LE bits. */
- }
- else
- {
- bep->saved = valid_addr (bep->addr, 1);
- if (bep->saved)
- {
- read_child (bep->addr, &bep->savedbyte, 1);
- write_child (bep->addr, &int03, 1);
- }
- }
- }
- /* ---------------------------------------------------------------------- */
- /* Un-patch code. */
- static void
- deactivate_breakpoints (void)
- { int b;
- BP_ENTRY *bep;
-
- for (b = 0, bep = breakpoint_table; b < breakpoint_count; b++, bep++)
- if (bep->saved)
- write_child (bep->addr, &bep->savedbyte, 1);
- }
- /* ---------------------------------------------------------------------- */
- static int
- get_breakpoint (BP_TYPE type, int length, word32 addr)
- { int b;
-
- for (b = 0; b < breakpoint_count; b++)
- if ((breakpoint_table[b].type == type) &&
- ((breakpoint_table[b].length == length) || (length == -1)) &&
- (breakpoint_table[b].addr == addr))
- return b;
- return -1;
- }
- /* ---------------------------------------------------------------------- */
- static void
- reset_breakpoint (int b)
- { BP_ENTRY *del_bp = malloc (sizeof (BP_ENTRY));
-
- del_bp->addr = breakpoint_table[b].addr;
- del_bp->type = breakpoint_table[b].type;
- del_bp->length = breakpoint_table[b].length;
- del_bp->sub_type = breakpoint_table[b].sub_type;
- del_bp->count = breakpoint_table[b].count;
- strcpy (del_bp->condition, breakpoint_table[b].condition);
- put_undo (&breakpoint_undo, 1, (word32)del_bp, 1);
- breakpoint_table[b] = breakpoint_table[--breakpoint_count];
- breakpoint_table
- = realloc (breakpoint_table, breakpoint_count * sizeof (BP_ENTRY));
- }
- /* ---------------------------------------------------------------------- */
- static int
- set_breakpoint (BP_TYPE type, int length, word32 addr)
- { int b;
-
- b = breakpoint_count;
- breakpoint_table
- = realloc (breakpoint_table, ++breakpoint_count * sizeof (BP_ENTRY));
- breakpoint_table[b].addr = addr;
- breakpoint_table[b].type = type;
- breakpoint_table[b].length = length;
- breakpoint_table[b].sub_type = 0;
- breakpoint_table[b].count = 0;
- breakpoint_table[b].condition[0] = '\0';
- return b;
- }
- /* ---------------------------------------------------------------------- */
- static void
- format_type (char *output, char *input)
- { int ok;
- long temp = parse_expression (4, input, &ok);
-
- if (ok != ParseError_ok)
- temp = 4;
- switch (temp)
- { case 0:
- sprintf (output, "%ld (%s)", temp, "Code breakpoint");
- break;
- case 1:
- sprintf (output, "%ld (%s)", temp, "Data-write breakpoint");
- break;
- case 3:
- sprintf (output, "%ld (%s)", temp, "Data-read/write breakpoint");
- break;
- default:
- sprintf (output, "%ld (%s)", temp, "Invalid breakpoint type");
- break;
- }
- }
- /* ---------------------------------------------------------------------- */
- static void
- format_subt (char *output, char *input)
- { int ok;
- long temp = parse_expression (4, input, &ok);
-
- if (ok != ParseError_ok)
- temp = 3;
- switch (temp)
- { case 0:
- sprintf (output, "%ld (%s)", temp, "Normal breakpoint");
- break;
- case 1:
- sprintf (output, "%ld (%s)", temp, "Countdown breakpoint");
- break;
- case 2:
- sprintf (output, "%ld (%s)", temp, "Conditional breakpoint");
- break;
- default:
- sprintf (output, "%ld (%s)", temp, "Invalid breakpoint type");
- break;
- }
- }
- /* ---------------------------------------------------------------------- */
- static void
- init_type (char *output, char *input, word32 addr)
- { char *temp = alloca (16);
-
- sprintf (input, "%d", *(int *)addr);
- sprintf (temp, "%08lx", *(word32 *)addr);
- format_type (output, temp);
- }
- /* ---------------------------------------------------------------------- */
- static void
- init_subt (char *output, char *input, word32 addr)
- { char *temp = alloca (16);
-
- sprintf (input, "%d", *(int *)addr);
- sprintf (temp, "%08lx", *(word32 *)addr);
- format_subt (output, temp);
- }
- /* ---------------------------------------------------------------------- */
- static int
- edit_breakpoint (int bp_num)
- { word32 addr;
- int type = 0, sub_type = 0, count = 0, size = 4, ret = 5;
- char *condition = alloca (max_cols);
- static DIALOG_ITEM dialog_data[] = {
- {"Address :", 0 , 50, 1, format_addr, eval_word, init_addr, editor},
- {"Type :", 0 , 30, 1, format_type, eval_word, init_type, editor},
- {"Class :", 0 , 30, 1, format_subt, eval_word, init_subt, editor},
- {"Count :", 0 , 10, 1, format_deci, eval_word, init_deci, editor},
- {"Size :", 0 , 02, 1, format_deci, eval_word, init_deci, editor},
- {"Condition:", 0 , 70, 1, format_asis, eval_asis, init_asis, editor},
- {0 , 0 , 0 , 0, 0 , 0 , 0 , 0 }
- };
- static BUTTON_ITEM button_data[] = {
- {" OK ", 0, action_done},
- {" Cancel ", 0, action_done},
- {0 , 0, 0 }
- };
-
- addr = breakpoint_table[bp_num].addr;
- type = breakpoint_table[bp_num].type;
- sub_type = breakpoint_table[bp_num].sub_type;
- count = breakpoint_table[bp_num].count;
- size = breakpoint_table[bp_num].length;
- strcpy(condition,breakpoint_table[bp_num].condition);
- if (size != 1 && size != 2)
- size = 4;
-
- dialog_data[0].return_addr = (word32)&addr;
- dialog_data[1].return_addr = (word32)&type;
- dialog_data[2].return_addr = (word32)&sub_type;
- dialog_data[3].return_addr = (word32)&count;
- dialog_data[4].return_addr = (word32)&size;
- dialog_data[5].return_addr = (word32)condition;
- dialog ("Edit Breakpoint", dialog_data, button_data, &ret);
- if (ret == 1)
- { if (size != 1 && size != 2)
- size = 4;
- breakpoint_table[bp_num].addr = addr;
- breakpoint_table[bp_num].type = type;
- breakpoint_table[bp_num].sub_type = sub_type;
- breakpoint_table[bp_num].count = count;
- breakpoint_table[bp_num].length = size;
- strcpy(breakpoint_table[bp_num].condition,condition);
- return (0);
- } else
- return (1);
- }
- /* ---------------------------------------------------------------------- */
- /* From ORIGIN skip COUNT instructions forward (positive count) or
- backwards (negative count). Backwards skipping cannot be assumed to
- be working 100% perfectly, but in the presense of debug information
- it is probably very, very close.
-
- This function works poorly close to the extremes of segments. */
-
- static int
- code_skip (int origin, int count)
- {
- int len, *next, i, j, k, instcount, done, leave;
- char *state, *inst, *source;
-
- if (count >= 0)
- { while (count-- > 0)
- if (valid_instaddr (origin))
- { unassemble_proper (origin, &len);
- origin += len;
- } else
- origin ++;
- return origin;
- } else
- { count = -count;
- instcount = MAXINSTLEN * (count + 16) + 1;
- next = alloca (instcount * sizeof (int));
- memset (next, 0, instcount * sizeof (int));
- state = alloca (instcount * sizeof (char));
- memset (state, 0, instcount * sizeof (char));
-
- done = 0;
- do
- { for (i = 0; i < 2 * count; i++)
- { done++;
- j = origin - done;
- if (valid_instaddr (j))
- { inst = unassemble_proper (j, &len);
- source = unassemble_source (j);
- next[done] = j + len;
- if (source)
- { leave = 0;
- k = done;
- while (j < origin && state[k] == 0 && !leave)
- { j++;
- state[k--] = 2;
- while (len-- > 1)
- { j++;
- state[k--] = 3;
- }
- /* -------------------------------------------------------------------
- - Since code and data is "never" mixed in 32 bit code we don't need this.
- -------------------------------------------------------------------*/
- #if 0
- leave = (strncmp (inst, "jmp", 3) == 0
- || strncmp (inst, "ret", 3) == 0
- || strncmp (inst, "iret", 4) == 0);
- #endif
- if (!leave)
- inst = unassemble_proper (j, &len);
- }
- }
- } else
- { state[done] = 2;
- next[done] = j + 1;
- }
- }
- j = 1;
- k = count;
- while (k > 0 && j <= done && state[j] >= 2)
- if (state[j++] == 2)
- k--;
- } while (k > 0 && done + 2 * count <= instcount);
- if (k == 0)
- return origin - j + 1;
- else
- { i = origin;
- k = 0;
- while (count > 0 && k <= done)
- { leave = 0;
- j = MAXINSTLEN;
- while (!leave && j > 1)
- if (j + k <= done && next[j + k] == i)
- leave = 1;
- else
- j--;
- if (!leave)
- i--, k++;
- else
- i -= j, k += j;
- count--;
- /* -------------------------------------------------------------------
- - If there is a source line, that also counts toward the number of lines
- ------------------------------------------------------------------- */
- source = unassemble_source (i);
- if (source)
- count--;
- }
- return i;
- }
- }
- }
- /* ---------------------------------------------------------------------- */
- static void
- code_pane_goto (word32 v)
- { int i = 0;
-
- if (v >= code_dump_origin && v <= code_dump_last)
- { while (code_pane_pos[i] < v)
- i++;
- if (code_pane_pos [i] == code_pane_pos[i+1])
- i++;
- } else
- { code_dump_origin = v;
- if (valid_instaddr (v) && unassemble_source (v))
- i++;
- }
- if (pane == 0)
- pane_pos = i;
- else
- pane_positions[0] = i;
- }
- /* ---------------------------------------------------------------------- */
- inline static void
- go (int bp)
- {
- /* ------------------------------------------------------------
- - These modifications cannot be undone after run/trace/step
- ------------------------------------------------------------ */
- reinit_undo (&data_undo);
- reinit_undo (®ister_undo);
- reinit_undo (&npx_undo);
- if (bp)
- activate_breakpoints ();
- is_in_running_mode = 1;
- run_child ();
- is_in_running_mode = 0;
- if (bp)
- deactivate_breakpoints ();
- }
- /* ---------------------------------------------------------------------- */
- static void
- trace_over_bp (void)
- { int len;
- char *inst;
- word32 old_addr = a_tss.tss_eip;
-
- inst = unassemble_proper (old_addr, &len);
- if (strcmp (inst, "popf") == 0 || strcmp (inst, "pushf") == 0)
- { edi.dr[7] = 0;
- edi.dr[7] |= ((BP_Code << 16) | 2);
- edi.dr[0] = old_addr + len + edi.app_base;
- edi.dr[7] |= 0x00000300L;
-
- is_in_running_mode = 1;
- run_child ();
- is_in_running_mode = 0;
- } else
- { a_tss.tss_eflags |= 0x0100;
- edi.dr[7] = 0;
- is_in_running_mode = 1;
- run_child ();
- is_in_running_mode = 0;
- a_tss.tss_eflags &= ~0x0100;
- }
- }
- /* ---------------------------------------------------------------------- */
- static char condition[200];
- /* ---------------------------------------------------------------------- */
- static void
- go_til_true_stop (int *terminated, int *int03hit)
- { int b, i, keep_going = 1;
-
- while (keep_going)
- { go (1);
- i = a_tss.tss_irqn;
- *terminated = (i == 0x21) && (a_tss.tss_eax & 0xff00) == 0x4c00;
- *int03hit = (i == 0x03) &&
- (get_breakpoint (BP_Code, -1, a_tss.tss_eip - 1) != -1);
- if (*terminated)
- a_tss.tss_eip -= 2; /* point back to Int 21h */
- else if (*int03hit)
- a_tss.tss_eip--; /* point back to Int 3 */
- if (*terminated)
- return;
-
- if (i == 1 || *int03hit)
- { int no;
-
- no = -1;
- for (b = 0; no == -1 && b <= 3; b++)
- if ((edi.dr[6] & (1 << b)) && (edi.dr[7] & (3 << (b * 2))))
- no = b;
- if (no != -1)
- { b = no;
- no = get_breakpoint ((edi.dr[7] >> (16 + 4 * no)) & 3,
- ((edi.dr[7] >> (18 + 4 * no)) & 3) + 1,
- edi.dr[no] - edi.app_base);
- if (no == -1)
- { no = b;
- no = get_breakpoint ((edi.dr[7] >> (16 + 4 * no)) & 3,
- -1, edi.dr[no] - edi.app_base);
- }
- }
- else if (*int03hit)
- no = get_breakpoint (BP_Code, -1, a_tss.tss_eip);
- if (no != -1)
- { switch (breakpoint_table[no].sub_type)
- { case 1: /* Count down */
- if (breakpoint_table[no].count)
- breakpoint_table[no].count--;
- else
- keep_going = 0;
- break;
- case 2: /* Conditional */
- { int ofs, satisfy;
-
- strcpy (condition, breakpoint_table[no].condition);
- satisfy = parse_expression(breakpoint_table[no].length,
- condition, &ofs);
- if (ofs != ParseError_ok)
- break;
- if (satisfy != 0)
- keep_going = 0;
- break;
- }
- default:
- keep_going = 0;
- }
- if (keep_going)
- trace_over_bp ();
- } else
- keep_going = 0;
- } else
- keep_going = 0;
- }
- }
- /* ---------------------------------------------------------------------- */
- static void
- step_over (int *terminated, int *int03hit, int len)
- { int b, has_break_point = 0;
- word32 old_addr = 0;
- int sub_type = 0, count = 0;
- char *cond = 0;
-
- b = get_breakpoint (BP_Code, -1, a_tss.tss_eip);
- if (b != -1)
- { old_addr = breakpoint_table[b].addr;
- sub_type = breakpoint_table[b].sub_type;
- count = breakpoint_table[b].count;
- cond = strdup (breakpoint_table[b].condition);
- reset_breakpoint (b);
- has_break_point = 1;
- }
- b = set_breakpoint (BP_Code, 0, a_tss.tss_eip + len);
- go_til_true_stop (terminated, int03hit);
- reset_breakpoint (b);
- if (has_break_point)
- { b = set_breakpoint (BP_Code, 0, old_addr);
- breakpoint_table[b].sub_type = sub_type;
- breakpoint_table[b].count = count;
- strcpy(breakpoint_table[b].condition, cond);
- free (cond);
- }
- }
- /* ---------------------------------------------------------------------- */
- static void
- step (int kind)
- { int i, b, len, terminated = 0, int03hit = 0, refmem;
- char *inst = 0;
-
- switch (kind)
- { case 0:
- inst = unassemble_proper (a_tss.tss_eip, &len);
- if (strcmp (inst, "popf") == 0 || strcmp (inst, "pushf") == 0)
- kind = 1; /* Push the right value of eflags (no trace flag). */
- break;
- case 1:
- if (first_step)
- kind = 3;
- else
- { inst = unassemble_proper (a_tss.tss_eip, &len);
- if (strncmp (inst, "loop", 4)
- && strncmp (inst, "call", 4)
- && strncmp (inst, "int", 3) )
- kind = 0;
- break;
- }
- }
- switch (kind)
- { case 0: /* "Trace" */
- a_tss.tss_eflags |= 0x0100;
- edi.dr[7] = 0;
- refmem = strchr (inst, '[') != 0;
- if (refmem)
- /* Assume that all access to code and stack segments are safe.
- This should hold unless you do something extra-ordinary dirty. */
- if (((a_tss.tss_ds == a_tss.tss_cs) || (a_tss.tss_ds == a_tss.tss_ss))
- && ((a_tss.tss_es == a_tss.tss_cs) || (a_tss.tss_es == a_tss.tss_ss))
- && ((a_tss.tss_fs == a_tss.tss_cs) || (a_tss.tss_fs == a_tss.tss_ss)
- || (strstr (inst, "fs:") == 0))
- && ((a_tss.tss_gs == a_tss.tss_cs) || (a_tss.tss_gs == a_tss.tss_ss)
- || (strstr (inst, "gs:") == 0)))
- refmem = 0;
- if (refmem)
- user_screen ();
- go (0);
- a_tss.tss_eflags &= ~0x0100;
- break;
- case 1: /* "Step Over" */
- user_screen ();
- step_over (&terminated, &int03hit, len);
- break;
- case 2: /* "Run" */
- user_screen ();
- if (get_breakpoint (BP_Code, -1, a_tss.tss_eip) != -1)
- trace_over_bp ();
- go_til_true_stop (&terminated, &int03hit);
- break;
- case 3: /* "Run to '_main'" */
- b = set_breakpoint (BP_Code, 0, main_entry);
- user_screen ();
- go_til_true_stop (&terminated, &int03hit);
- reset_breakpoint (b);
- break;
- }
- a_tss.tss_eflags &= ~0x0100; /* Clear TF, in case it's set by Ctrl-C */
- /* (in remote debugging.) */
- code_pane_goto (a_tss.tss_eip);
- debug_screen ();
- if (kind)
- re_start_transfer ();
- redraw (0);
- first_step = 0;
- i = a_tss.tss_irqn;
-
- if (terminated)
- { message (CL_Msg, "Program terminated normally, exit code is %d",
- (word8)a_tss.tss_eax);
- } else
- if (i == 1 || int03hit)
- { int no;
-
- no = -1;
- for (b = 0; no == -1 && b <= 3; b++)
- if ((edi.dr[6] & (1 << b)) && (edi.dr[7] & (3 << (b * 2))))
- no = b;
- if (no != -1)
- no = get_breakpoint ((edi.dr[7] >> (16 + 4 * no)) & 3,
- ((edi.dr[7] >> (18 + 4 * no)) & 3) + 1,
- edi.dr[no] - edi.app_base);
- else if (int03hit)
- no = get_breakpoint (BP_Code, -1, a_tss.tss_eip);
- if (no == -1)
- if (i == 1)
- no = get_breakpoint(BP_Code, -1, a_tss.tss_eip);
- if ((no != -1) && (kind > 0))
- { message (CL_Info, "%s %s breakpoint at %08lx triggered.",
- (breakpoint_table[no].sub_type == 0) ? "Normal" :
- ((breakpoint_table[no].sub_type == 1) ? "Count-down" :
- "Conditional"),
- (breakpoint_table[no].type == BP_Code) ? "code" :
- ((breakpoint_table[no].type == BP_Write) ? "data write" :
- "data read/write"),
- breakpoint_table[no].addr);
- }
- } else
- { if (i == 0x79)
- message (CL_Info, "Keyboard interrupt");
- else if (i == 0x09)
- message (CL_Info, "Ctrl-C pressed (exception 0x09)");
- else if (i == 0x75)
- { char *reason;
-
- save_npx ();
- if ((npx.status & 0x0241) == 0x0241)
- reason = "stack overflow";
- else if ((npx.status & 0x0241) == 0x0041)
- reason = "stack underflow";
- else if (npx.status & 1)
- reason = "invalid operation";
- else if (npx.status & 2)
- reason = "denormal operand";
- else if (npx.status & 4)
- reason = "divide by zero";
- else if (npx.status & 8)
- reason = "overflow";
- else if (npx.status & 16)
- reason = "underflow";
- else if (npx.status & 32)
- reason = "loss of precision";
- else
- reason = "?";
- message (CL_Error,
- "Numeric Exception (%s) at eip=0x%08lx", reason, npx.eip);
- load_npx ();
- }
- else if (i == 8 || (i >= 10 && i <= 14))
- message (CL_Error, "Exception %d (0x%02x) occurred, error code=%#lx",
- i, i, a_tss.tss_error);
- else
- message (CL_Error, "Exception %d (0x%02x) occurred", i, i);
- }
- }
- /* ---------------------------------------------------------------------- */
- static void
- draw_debug_frames (void)
- { frame (0, 1, main_x1, toplines + 1, active_pane_name);
- frame (main_x2, 1, cols - 1, toplines + 1, 0);
- frame (main_x1, 1, main_x2, toplines + 1, 0);
- frame (main_x3, toplines + 1, cols - 1, rows - 2, 0);
- frame (0, toplines + 1, main_x3, rows - 2, 0);
-
- if (!using_com_port_num)
- { put (main_x2, 1, "┬");
- put (main_x2, toplines + 1, "â”´");
- put (0, toplines + 1, "├");
- put (cols - 1, toplines + 1, "┤");
- put (main_x1, 1, "┬");
- put (main_x1, toplines + 1, "â”´");
- put (main_x3, toplines + 1, "┬");
- put (main_x3, rows - 2, "â”´");
- }
- }
- /* ---------------------------------------------------------------------- */
- static void
- draw_focused_frame (void)
- { int x1, x2, y1, y2;
-
- screen_attr = screen_attr_ffocus;
- switch (pane) /* Set focused pane */
- { case 1: /* Top middle */
- x1 = main_x1;
- x2 = main_x2;
- y1 = 1;
- y2 = toplines + 1;
- break;
- case 2: /* Top right */
- x1 = main_x2;
- x2 = cols - 1;
- y1 = 1;
- y2 = toplines + 1;
- break;
- case 3: /* Bottom right */
- x1 = main_x3;
- x2 = cols - 1;
- y1 = toplines + 1;
- y2 = rows - 2;
- break;
- case 4: /* Bottom left */
- x1 = 0;
- x2 = main_x3;
- y1 = toplines + 1;
- y2 = rows - 2;
- break;
- default: /* Top left */
- x1 = 0;
- x2 = main_x1;
- y1 = 1;
- y2 = toplines + 1;
- break;
- }
- if (pane < 1 || pane > 4)
- double_frame (x1, y1, x2, y2, active_pane_name);
- else
- double_frame (x1, y1, x2, y2, 0);
- screen_attr = screen_attr_normal;
- }
- /* ---------------------------------------------------------------------- */
- static void
- put_redraw (int x, int y, int width, int max_y, int offset, char *buf)
- { int buflen;
- buflen = strlen (buf);
- if (y <= max_y)
- putl (x, y, width, buf + ((offset < buflen) ? offset : buflen));
- }
- /* ---------------------------------------------------------------------- */
- void
- redraw_registers (char *buf)
- { int reg, x = main_x1 + 1, y = 2, width = main_x2 - main_x1 - 1;
-
- for (reg = reg_pane_origin; regs_type[reg]; reg++)
- { if (regs_type[reg] == 's')
- sprintf (buf, " %s %04x", regs_names[reg],
- *(unsigned short *)(regs_addr[reg]));
- else
- sprintf (buf, "%s %08lx", regs_names[reg], *(regs_addr[reg]));
- put_redraw (x, y++, width, toplines,
- pane_offset[REGISTER_PANE_NUM], buf);
- if (y > toplines)
- break;
- }
- while (y <= toplines)
- putl (x, y++, width, " ");
- if (pane == REGISTER_PANE_NUM)
- { screen_attr = screen_attr_focus;
- if (pane_pos >= toplines - 1)
- pane_pos = toplines - 2;
- highlight (main_x1 + 1, pane_pos + 2,
- main_x2 - main_x1 - 1);
- screen_attr = screen_attr_normal;
- }
- }
- /* ---------------------------------------------------------------------- */
- void
- redraw_flags (char *buf)
- { int f, x = main_x2 + 1, y = 2, width = cols - main_x2 - 2;
- static char flags[] = "c?p?a?zn?ido????";
-
- for (f = flag_pane_origin; flags[f]; f++)
- { if (flags[f] != '?')
- { sprintf (buf, "%c=%d", flags[f], (int)((a_tss.tss_eflags >> f) & 1));
- put_redraw (x, y++, width, toplines, pane_offset[FLAG_PANE_NUM], buf);
- }
- if (y > toplines)
- break;
- }
- while (y <= toplines)
- putl (x, y++, width, " ");
- if (pane == FLAG_PANE_NUM)
- { screen_attr = screen_attr_focus;
- if (pane_pos >= toplines - 1)
- pane_pos = toplines - 2;
- highlight (main_x2 + 1, pane_pos + 2,
- cols - main_x2 - 2);
- screen_attr = screen_attr_normal;
- }
- }
- /* ---------------------------------------------------------------------- */
- void
- redraw_breakpoints (char *buf)
- { int b, x = main_x3 + 1, y = toplines + 2, width = cols - main_x3 - 2;
- char *name;
- int32 delta;
-
- for (b = breakpoint_origin;
- b < breakpoint_origin + bottomlines / 2 && b < breakpoint_count;
- b++)
- { switch (breakpoint_table[b].type)
- { case BP_Code:
- sprintf (buf, "%-20s", "C ");
- break;
- case BP_Write:
- sprintf (buf, "%-20s, %d","DW",
- breakpoint_table[b].length);
- break;
- case BP_Read:
- sprintf (buf, "%-20s, %d","DR",
- breakpoint_table[b].length);
- break;
- }
- switch (breakpoint_table[b].sub_type)
- { case 0:
- sprintf (buf + 3, "Norm.");
- break;
- case 1:
- sprintf (buf + 3, "Count");
- break;
- case 2:
- sprintf (buf + 3, "Cond.");
- break;
- }
- buf[8] = ' ';
- putl (x, y, width, buf);
- screen_attr = screen_attr_addr;
- sprintf(buf, "%08lx", breakpoint_table[b].addr);
- if (width > 12)
- putl(x + 12, y, width - 12 > 8 ? 8 : width - 12, buf);
- y++;
- screen_attr = screen_attr_normal;
- name = syms_val2name (breakpoint_table[b].addr, &delta);
- if (name[0] != '0')
- if (delta && strlen (name) < width)
- sprintf (buf, " %s+%#lx", name, delta);
- else
- sprintf (buf, " %-*s", width, name);
- else
- buf[0] = '\0';
- put_redraw (x, y++, width, rows,
- pane_offset[BREAKPOINT_PANE_NUM], buf);
- }
- if (breakpoint_count == 0)
- putl (x, y++, width, "No breakpoints");
- while (y < rows - 2)
- putl (x, y++, width, "");
- if (pane == BREAKPOINT_PANE_NUM)
- { screen_attr = screen_attr_focus;
- if (breakpoint_origin >= breakpoint_count)
- breakpoint_origin = breakpoint_count ? breakpoint_count - 1 : 0;
- if (breakpoint_origin + pane_pos >= breakpoint_count)
- pane_pos = breakpoint_count - breakpoint_origin;
- if (2 * pane_pos + 2 > bottomlines)
- pane_pos = bottomlines / 2 - 1;
- if (pane_pos < 0)
- pane_pos = 0;
- else
- { highlight (main_x3 + 1, toplines + 2 + 2 * pane_pos,
- cols - main_x3 - 2);
- if (2 * pane_pos + 1 < bottomlines)
- highlight (main_x3 + 1, toplines + 3 + 2 * pane_pos,
- cols - main_x3 - 2);
- }
- screen_attr = screen_attr_normal;
- }
- }
- /* ---------------------------------------------------------------------- */
- void
- redraw_data (char *buf)
- { word32 p = data_dump_origin;
- int b, x, y = toplines + 2, ok, width = main_x3 - 1;
- unsigned char data[8], xpos[8];
- int buflen;
-
- for (x = 0; x < 8; x++)
- xpos[x] = 1 + ((data_dump_size == 1) ? (x * 3) :
- ((data_dump_size == 2) ? ((x / 2) * 5 + (~x & 1) * 2) :
- ((x / 4) * 9 + (~x & 3) * 2)));
- while (y < rows - 2)
- { if ((ok = valid_addr (p, 8)))
- read_child (p, data, 8);
-
- screen_attr = screen_attr_addr;
- sprintf (buf, "%08lx:",p);
- putl (1, y, 9, buf);
- sprintf (buf, "%70s", " ");
- for (x = 0; x < 8; x++)
- if (ok || valid_addr (p + x, 1))
- { if (!ok)
- read_child (p + x, data + x, 1);
- buf[xpos[x]] = hexchars[data[x] >> 4];
- buf[xpos[x] + 1] = hexchars[data[x] & 0xf];
- buf[28 + x] = (data[x] ? data[x] : '.');
- } else
- buf[xpos[x]] = buf[xpos[x + 1]] = buf[28 + x] = '?';
- screen_attr = screen_attr_normal;
- buflen = strlen (buf);
- putl (10, y, width - 9, buf + ((pane_offset[DATA_PANE_NUM] < buflen)
- ? pane_offset[DATA_PANE_NUM] : buflen));
- screen_attr = screen_attr_break;
- for (x = 0; x < 8; x++)
- for (b = 0; b < breakpoint_count; b++)
- if (breakpoint_table[b].type != BP_Code
- && p + x >= breakpoint_table[b].addr
- && p + x < (breakpoint_table[b].addr
- + breakpoint_table[b].length))
- { if (xpos[x] >= pane_offset[DATA_PANE_NUM])
- highlight (xpos[x] + 10 - pane_offset[DATA_PANE_NUM], y, 2);
- if (x + 28 >= pane_offset[DATA_PANE_NUM])
- highlight (38 + x - pane_offset[DATA_PANE_NUM], y, 1);
- }
- screen_attr = screen_attr_normal;
- p += 8;
- y++;
- }
- data_dump_last = p - 1;
- if (pane == DATA_PANE_NUM)
- { int offset;
- int x = pane_pos & 7, y = pane_pos >> 3;
-
- while (y >= bottomlines)
- { y--;
- pane_pos -= 8;
- }
- screen_attr = screen_attr_focus;
- if ((38 + x + data_dump_size <= main_x3) &&
- (x + 28 >= pane_offset[INFO_PANE_NUM]))
- highlight (38 + x - pane_offset[DATA_PANE_NUM],
- toplines + 2 + y, data_dump_size);
- switch (data_dump_size)
- { case 1:
- offset = 1 + 3 * x - pane_offset[DATA_PANE_NUM];
- if (13 + 3 * x <= main_x3)
- if (offset >= 0)
- highlight (11 + 3 * x - pane_offset[DATA_PANE_NUM],
- toplines + 2 + y, 2);
- else if (offset > -1)
- highlight (10, toplines + 2 + y, 2 + offset);
- break;
- case 2:
- offset = 1 + 5 * (x >> 1) - pane_offset[DATA_PANE_NUM];
- if (15 + 5 * (x >> 1) <= main_x3)
- if (offset >= 0)
- highlight (11 + 5 * (x >> 1) - pane_offset[DATA_PANE_NUM],
- toplines + 2 + y, 4);
- else if (offset > -4)
- highlight (10, toplines + 2 + y, 4 + offset);
- break;
- case 4:
- offset = 1 + 9 * (x >> 2) - pane_offset[DATA_PANE_NUM];
- if (19 + 9 * (x >> 2) <= main_x3)
- if (offset >= 0)
- highlight (11 + 9 * (x >> 2) - pane_offset[DATA_PANE_NUM],
- toplines + 2 + y, 8);
- else if (offset > -8)
- highlight (10, toplines + 2 + y, 8 + offset);
- break;
- }
- screen_attr = screen_attr_normal;
- }
- }
- /* ---------------------------------------------------------------------- */
- void
- redraw_code (char *buf)
- { word32 p = code_dump_origin, width = main_x1 - 1;
- int y = 2, len, source = 0, buflen;
- char *txt;
-
- while (y <= toplines)
- { source = !source;
- code_pane_pos[y - 2] = p;
- if (source)
- { txt = unassemble_source (p);
- if (txt)
- { screen_attr = screen_attr_source;
- buflen = strlen (txt);
- putl (1, y++, width, txt + ((pane_offset[CODE_PANE_NUM] < buflen)
- ? pane_offset[CODE_PANE_NUM] : buflen));
- }
- } else
- { int temp_len;
-
- if (valid_instaddr (p))
- txt = unassemble_proper (p, &len);
- else
- txt = "?", len = 1;
- sprintf (buf, "%08lx%c", p, p == a_tss.tss_eip ? '>' : ' ');
- screen_attr = (get_breakpoint (BP_Code, -1, p) == -1
- ? screen_attr_addr : screen_attr_break);
- temp_len = strlen(buf);
- putl (1, y++, (width > temp_len ? temp_len : width), buf);
- if (width > temp_len)
- { screen_attr = (get_breakpoint (BP_Code, -1, p) == -1
- ? screen_attr_asm : screen_attr_break);
- buflen = strlen (txt);
- putl(temp_len + 1,y - 1,(width - temp_len),
- txt + ((pane_offset[CODE_PANE_NUM] < buflen)
- ? pane_offset[CODE_PANE_NUM] : buflen));
- }
- p += len;
- }
- }
- code_pane_pos[y - 2] = p + 1;
- code_dump_last = p - 1;
- if (pane == CODE_PANE_NUM)
- { screen_attr = screen_attr_focus;
- if (pane_pos >= toplines - 1)
- pane_pos = toplines - 2;
- highlight (1, pane_pos + 2, main_x1 - 1);
- }
- screen_attr = screen_attr_normal;
- }
- /* ---------------------------------------------------------------------- */
- void
- redraw_npx (char *buf)
- { int i, y = 2, width = main_x1 - 1;
- static char *rtype[] = { "Near", "-Inf", "+Inf", "Zero" };
-
- save_npx ();
- sprintf (buf,
- "Control: %04lx PR=%s UN=%s OV=%s ZD=%s DN=%s IV=%s Rnd=%s",
- npx.control & 0xffff,
- (npx.control & (1 << 5)) ? "N" : "Y",
- (npx.control & (1 << 4)) ? "N" : "Y",
- (npx.control & (1 << 3)) ? "N" : "Y",
- (npx.control & (1 << 2)) ? "N" : "Y",
- (npx.control & (1 << 1)) ? "N" : "Y",
- (npx.control & (1 << 0)) ? "N" : "Y",
- rtype[(npx.control >> 10) & 3]);
- put_redraw (1, y++, width, toplines, pane_offset[NPX_PANE_NUM], buf);
- sprintf (buf,
- "Status: %04lx PR=%s UN=%s OV=%s ZD=%s DN=%s IV=%s ST=%s",
- npx.status & 0xffff,
- (npx.status & (1 << 5)) ? "Y" : "N",
- (npx.status & (1 << 4)) ? "Y" : "N",
- (npx.status & (1 << 3)) ? "Y" : "N",
- (npx.status & (1 << 2)) ? "Y" : "N",
- (npx.status & (1 << 1)) ? "Y" : "N",
- (npx.status & (1 << 0)) ? "Y" : "N",
- (npx.status & (1 << 6)) ? "Y" : "N");
- put_redraw (1, y++, width, toplines, pane_offset[NPX_PANE_NUM], buf);
- sprintf (buf, "%19sC3=%d C2=%d C1=%d C0=%d",
- "",
- (npx.status & (1 << 14)) != 0,
- (npx.status & (1 << 10)) != 0,
- (npx.status & (1 << 9)) != 0,
- (npx.status & (1 << 8)) != 0);
- put_redraw (1, y++, width, toplines, pane_offset[NPX_PANE_NUM], buf);
- for (i = 0; i < 8; i++)
- {
- /* ---------------------------------------------------------------------
- - We assume that `long double' is the same type as npx.reg[i].
- - It would be sensible to check that the sizes match, but they
- - don't! For alignment reasons, `sizeof (long double)' is 12.
- ---------------------------------------------------------------------*/
- long double d;
- int tag;
- int tos = (npx.status >> 11) & 7;
- int exp = (int)npx.reg[i].exponent - 16382;
- char *dstr = alloca (30);
-
- dstr[0] = (npx.reg[i].sign) ? '-' : '+';
- dstr[1] = '\0';
- tag = (npx.tag >> (((i + tos) & 7) * 2)) & 3;
- switch (tag)
- { case 0:
- if (abs (exp) < 1000)
- { d = *((long double*)(npx.reg + i));
- /* --------------------------------------------------------------------
- - sprintf does not (djgpp 1.11m3) handle long doubles.
- -------------------------------------------------------------------- */
- sprintf(dstr,"%+.16g", (double) d);
- } else
- sprintf (dstr, "Valid, %s, and %s",
- npx.reg[i].sign ? "negative" : "positive",
- exp > 0 ? "huge" : "tiny");
- break;
- case 1:
- strcat (dstr, "Zero");
- break;
- case 2:
- if (npx.reg[i].exponent == 0x7fff)
- if (npx.reg[i].sig3 == 0x8000 && npx.reg[i].sig2 == 0x0000
- && npx.reg[i].sig1 == 0x0000 && npx.reg[i].sig0 == 0x0000)
- strcat (dstr, "Inf");
- else
- strcat (dstr, "NaN");
- else
- sprintf (dstr, "Special");
- break;
- case 3:
- sprintf (dstr, "Empty");
- break;
- }
- sprintf (buf, "st(%d): %d %04x %04x%04x%04x%04x %s",
- i,
- npx.reg[i].sign, npx.reg[i].exponent,
- npx.reg[i].sig3, npx.reg[i].sig2,
- npx.reg[i].sig1, npx.reg[i].sig0,
- dstr);
- put_redraw (1, y++, width, toplines,
- pane_offset[NPX_PANE_NUM], buf);
- if (y > toplines)
- break;
- }
- while (y <= toplines)
- putl (1, y++, width, " ");
- load_npx ();
- if (pane == NPX_PANE_NUM)
- { screen_attr = screen_attr_focus;
- if (pane_pos >= toplines - 1)
- pane_pos = toplines - 2;
- highlight (1, pane_pos + 2, main_x1 - 1);
- screen_attr = screen_attr_normal;
- }
- }
- /* ---------------------------------------------------------------------- */
- void
- redraw_stack (char *buf)
- { int line, y = 2, no = -stack_dump_origin, width = main_x1 - 1;
- unsigned char eipcode[4];
- word32 delta, v = a_tss.tss_ebp;
- word32 vaddr = a_tss.tss_eip;
- int first = 1;
-
- stack_dump_more = 0;
- while (valid_instaddr (vaddr))
- { if (no++ >= 0)
- if (y >= toplines)
- { stack_dump_more = 1;
- break;
- } else
- { char *symaddr, *sourceaddr, *sourcefile;
- int len;
- char *mybuf;
-
- symaddr = syms_val2name (vaddr, &delta);
- sourcefile = syms_val2line (vaddr, &line, 0);
- if (sourcefile)
- sprintf (sourceaddr = alloca (cols + strlen (sourcefile)),
- ", line %d in file %s", line, sourcefile);
- else if (delta)
- sprintf (sourceaddr = alloca (cols), "%+ld", (long) delta);
- else
- sourceaddr = "";
- len = 15 + strlen (symaddr) + strlen (sourceaddr);
- mybuf = alloca (len + 15);
- sprintf (mybuf, "%08lx: %s%s", vaddr, symaddr, sourceaddr);
- stack_dump_last = (y - 2) / 2;
- stack_dump_pos[stack_dump_last] = vaddr;
- put_redraw (1, y++, width, toplines,
- pane_offset[STACK_PANE_NUM], mybuf);
- sprintf (mybuf, " Stack frame: %08lx", v);
- put_redraw (1, y++, width, toplines,
- pane_offset[STACK_PANE_NUM], mybuf);
- }
- if (first)
- { first = 0;
- read_child (vaddr, eipcode, 3);
- /* ---------------------------------------------------------------------
- - We look directly at the bit pattern instead of using disassembly;
- - the bit patterns are those generated by gcc. In general we
- - cannot expect to be able to follow a non-gcc stack anyway.
- --------------------------------------------------------------------- */
- if ((eipcode[0] == 0x55 && eipcode[1] == 0x89 && eipcode[2] == 0xe5)
- || eipcode[0] == 0xc3)
- {
- /* ---------------------------------------------------------------------
- - In this case where we are looking at `Push Ebp//Mov Ebp,Esp'
- - or `Ret', only the return address is on the stack; I believe
- - this only to happen in the innermost activation record.
- --------------------------------------------------------------------- */
- if (valid_addr (a_tss.tss_esp, 4))
- read_child (a_tss.tss_esp, &vaddr, 4);
- else
- break;
- } else
- { if (eipcode[0] == 0x89 && eipcode[1] == 0xe5)
- /* ---------------------------------------------------------------------
- - When looking at `Mov Esp,Ebp' the next stack frame is on
- - the stack and pointed to by the stack pointer. We are
- - actually in the same situation after `Mov Esp,Ebp' which
- - is generated by gcc with the -m486 option. This case is,
- - however, handled perfectly by using the base pointer.
- --------------------------------------------------------------------- */
- v = a_tss.tss_esp;
- if (v >= a_tss.tss_esp && v < 0x80000000L && valid_addr (v, 8))
- { read_child (v + 4, &vaddr, 4);
- read_child (v, &v, 4);
- } else
- break;
- }
- } else
- { if (v >= a_tss.tss_esp && v < 0x80000000L && valid_addr (v, 8))
- { read_child (v + 4, &vaddr, 4);
- read_child (v, &v, 4);
- } else
- break;
- }
- }
- while (y <= toplines)
- putl (1, y++, width, " ");
- if (pane == STACK_PANE_NUM)
- { screen_attr = screen_attr_focus;
- if (pane_pos * 2 + 2 > toplines - 1)
- pane_pos = (toplines - 1) / 2 - 1;
- if (pane_pos < 0)
- pane_pos = 0;
- else
- { if (pane_pos > stack_dump_last)
- pane_pos = stack_dump_last;
- highlight (1, pane_pos * 2 + 2, main_x1 - 1);
- }
- screen_attr = screen_attr_normal;
- }
- }
- /* ---------------------------------------------------------------------- */
- void
- redraw_info (char *buf)
- { int y = 2, width = main_x1 - 1;
- long ul;
- char *s = alloca (20);
- _go32_dpmi_meminfo info;
- _go32_dpmi_registers regs;
-
- sprintf (buf, "Debugger version ............: %d.%02d %s",
- MAJOR_VER, MINOR_VER,
- MAJOR_VER == 0 ? "beta" : "");
- put_redraw (1, y++, width, toplines, pane_offset[INFO_PANE_NUM], buf);
- _go32_dpmi_get_free_memory_information (&info);
- switch (_go32_info_block.run_mode)
- { case _GO32_RUN_MODE_RAW:
- sprintf (s, "Raw");
- break;
- case _GO32_RUN_MODE_XMS:
- sprintf (s, "Xms");
- break;
- case _GO32_RUN_MODE_VCPI:
- sprintf (s, "Vcpi");
- break;
- case _GO32_RUN_MODE_DPMI:
- sprintf (s, "Dpmi %d.%02x",
- _go32_info_block.run_mode_info >> 8,
- _go32_info_block.run_mode_info & 0xff);
- break;
- default:
- sprintf (s, "Unknown");
- }
- sprintf (buf, "Running mode ................: %s", s);
- put_redraw (1, y++, width, toplines, pane_offset[INFO_PANE_NUM], buf);
- if (y <= toplines)
- putl (1, y++, width, "");
-
- ul = info.total_physical_pages;
- if (ul > 0)
- { ul <<= 12;
- sprintf (buf, "Total physical memory .......: %lu KB", ul >> 10);
- put_redraw (1, y++, width, toplines, pane_offset[INFO_PANE_NUM], buf);
- }
- ul = info.available_physical_pages
- ? info.available_physical_pages << 12
- : info.available_memory;
- sprintf (buf, "Remaining physical memory ...: %lu KB", ul >> 10);
- put_redraw (1, y++, width, toplines, pane_offset[INFO_PANE_NUM], buf);
- ul = info.available_memory;
- sprintf (buf, "Remaining virtual memory ....: %lu KB", ul >> 10);
- put_redraw (1, y++, width, toplines, pane_offset[INFO_PANE_NUM], buf);
- ul = info.free_linear_space << 12;
- if (ul >= 0)
- { sprintf (buf, "Free linear space ...........: %ld KB", ul >> 10);
- put_redraw (1, y++, width, toplines, pane_offset[INFO_PANE_NUM], buf);
- }
- /* ----------------------------------------------------------------
- - Remember that Dos memory is only made available of direct request;
- - using 0xffff does not count as a request.
- ---------------------------------------------------------------- */
- regs.h.ah = 0x48;
- regs.x.bx = 0xffff;
- regs.x.ss = regs.x.sp = 0;
- /* ----------------------------------------------------------
- - The call _go32_dpmi_simulate_int () causes the program
- - to hang under XMS mode.
- ---------------------------------------------------------- */
- if (_go32_info_block.run_mode != _GO32_RUN_MODE_XMS)
- _go32_dpmi_simulate_int (0x21, ®s);
- ul = regs.x.bx << 4;
- sprintf (buf, "Free dos memory .............: %ld %s",
- ul > 8192 ? ul >> 10 : ul,
- ul > 8192 ? "KB" : "Bytes");
- put_redraw (1, y++, width, toplines, pane_offset[INFO_PANE_NUM], buf);
- if (y <= toplines)
- putl (1, y++, width, "");
- sprintf (buf, "Ctrl-C checking .............: %s",
- getcbrk () ? "On" : "Off");
- put_redraw (1, y++, width, toplines, pane_offset[INFO_PANE_NUM], buf);
- if (y <= toplines)
- putl (1, y++, width, "");
-
- sprintf (buf, "Program text ................: %08lx - %08lx",
- areas[A_text].first_addr, areas[A_text].last_addr);
- put_redraw (1, y++, width, toplines, pane_offset[INFO_PANE_NUM], buf);
- sprintf (buf, "Program data ................: %08lx - %08lx",
- areas[A_data].first_addr, areas[A_data].last_addr);
- put_redraw (1, y++, width, toplines, pane_offset[INFO_PANE_NUM], buf);
- sprintf (buf, "Program bss .................: %08lx - %08lx",
- areas[A_bss].first_addr, areas[A_bss].last_addr);
- put_redraw (1, y++, width, toplines, pane_offset[INFO_PANE_NUM], buf);
- sprintf (buf, "Program stack ...............: %08lx - %08lx",
- areas[A_stack].first_addr, areas[A_stack].last_addr);
- put_redraw (1, y++, width, toplines, pane_offset[INFO_PANE_NUM], buf);
- if (y <= toplines)
- putl (1, y++, width, "");
- sprintf (buf, "Using com port number .......: %d",
- using_com_port_num);
- put_redraw (1, y++, width, toplines, pane_offset[INFO_PANE_NUM], buf);
- sprintf (buf, "Using symbol file ...........: %s%s.%s",
- sympath, symname, symext);
- put_redraw (1, y++, width, toplines, pane_offset[INFO_PANE_NUM], buf);
- while (y <= toplines)
- putl (1, y++, width, " ");
- }
- /* ---------------------------------------------------------------------- */
- void
- redraw_whereis (char *buf)
- { int y = 2, width = main_x1 - 1, i = whereis_origin;
- char *s;
-
- while (y <= toplines)
- if (i < whereis_sym_count)
- { s = syms_makewild (whereis_pane_sym[i++]);
- put_redraw (1, y++, width, toplines,
- pane_offset[WHEREIS_PANE_NUM], s);
- } else
- putl (1, y++, width, " ");
- if (pane == WHEREIS_PANE_NUM)
- { screen_attr = screen_attr_focus;
- if (pane_pos >= toplines - 1)
- pane_pos = toplines - 2;
- if (whereis_sym_count)
- highlight (1, pane_pos + 2, main_x1 - 1);
- screen_attr = screen_attr_normal;
- }
- }
- /* ---------------------------------------------------------------------- */
- void
- redraw_module (char *buf)
- { int y = 2, width = main_x1 - 1, i = module_origin;
-
- while (y <= toplines)
- if (i < module_text_count)
- put_redraw (1, y++, width, toplines,
- pane_offset[MODULE_PANE_NUM], module_pane_text[i++]);
- else
- putl (1, y++, width, " ");
- if (pane == MODULE_PANE_NUM)
- { screen_attr = screen_attr_focus;
- if (pane_pos >= toplines - 1)
- pane_pos = toplines - 2;
- if (module_text_count)
- highlight (1, pane_pos + 2, main_x1 - 1);
- screen_attr = screen_attr_normal;
- }
- }
- /* ---------------------------------------------------------------------- */
- void
- redraw_help (char *buf)
- { int y = 2, width = main_x1 - 1, i = help_origin;
-
- while (y <= toplines)
- if (i < help_text_count)
- { screen_attr = ((*help_pane_text[i] != ' ')
- ? screen_attr_help : screen_attr_normal);
- put_redraw (1, y++, width, toplines,
- pane_offset[HELP_PANE_NUM], help_pane_text[i++]);
- } else
- putl (1, y++, width, " ");
- if (pane == HELP_PANE_NUM)
- { screen_attr = screen_attr_focus;
- if (pane_pos >= toplines - 1)
- pane_pos = toplines - 2;
- if (help_text_count)
- highlight (1, pane_pos + 2, main_x1 - 1);
- screen_attr = screen_attr_normal;
- }
- }
- /* --
- static char *st_fmt = "%04x %04x %04x %04x %04x %04x %08lx %08lx";
- -- */
- /* ---------------------------------------------------------------------- */
- void
- redraw (int first)
- { char *buf = alloca (1024);
-
- debug_screen ();
- screen_attr = ScreenAttrib = screen_attr_normal;
- if (first == -1)
- { screen_attr = screen_attr_resize;
- clear_screen();
- }
- draw_debug_frames ();
- if (first == -1) /* For resizing */
- { put_screen (debug_screen_save);
- return;
- }
- draw_focused_frame ();
-
- redraw_registers (buf);
- redraw_flags (buf);
- redraw_breakpoints (buf);
- redraw_data (buf);
- if (code_pane_active)
- redraw_code (buf);
- if (npx_pane_active)
- redraw_npx (buf);
- if (stack_pane_active)
- redraw_stack (buf);
- if (info_pane_active)
- redraw_info (buf);
- if (whereis_pane_active)
- redraw_whereis (buf);
- if (module_pane_active)
- redraw_module (buf);
- if (help_pane_active)
- redraw_help (buf);
- screen_attr = st_ln_attr;
-
- /* --
- asm ("push %ebp \n\
- push %esp \n\
- push %ss \n\
- push %gs \n\
- push %fs \n\
- push %es \n\
- push %ds \n\
- push %cs \n\
- push _st_fmt \n\
- push $_StatusLine \n\
- call _sprintf \n\
- add $0x28, %esp \n\
- ");
- st_fmt[0] += 0;
- -- */
-
- putl (0, rows - 1, cols, StatusLine);
- if (running_xsupport)
- redraw_xsupport (buf);
- else
- show_menu_bar (Main_Menu);
- free (buf);
- }
- /* ---------------------------------------------------------------------- */
- static void
- init_module (void)
- {
- char *s;
-
- s = malloc(25);
- s = "Modules listing:";
- module_pane_text = realloc (module_pane_text,
- (++module_text_count) * sizeof (char *));
- module_pane_text[module_text_count - 1] = strdup (s);
- free(s);
- s = get_module(module_text_count - 1);
- while (!undefined_symbol)
- {
- module_pane_text = realloc (module_pane_text,
- (++module_text_count) * sizeof (char *));
- module_pane_text[module_text_count - 1] = strdup (s);
- free(s);
- s = get_module(module_text_count - 1);
- }
- undefined_symbol = 0;
- }
- /* ---------------------------------------------------------------------- */
- static void
- put_help_line(const char *str)
- {
- help_pane_text = realloc (help_pane_text,
- (++help_text_count) * sizeof (char *));
- help_pane_text[help_text_count - 1] = strdup (str);
-
- }
- /* ---------------------------------------------------------------------- */
- static void
- init_help (void)
- { put_help_line("----------------------------------------------------------");
- put_help_line("GLOBAL KEY BINDINGS:");
- put_help_line(" ");
- put_help_line(" C-x C-c Quit debugger. You will be prompted first.");
- put_help_line(" C-x C-v Save or load debugger context.");
- put_help_line(" C-r Run program.");
- put_help_line(" C-h Make Help pane active.");
- put_help_line(" BS Make Help pane active.");
- put_help_line(" C-x C-w Write active pane contents to a file. Only");
- put_help_line(" the visible portion of the pane is saved.");
- put_help_line(" C-x C-f Display contents of log file.");
- put_help_line(" C-x m Toggle between color/monochrome mode.");
- put_help_line(" C-x C-e Evaluate an expression and display result");
- put_help_line(" in the minibuffer.");
- put_help_line(" C-z Show program output. Press any key to return");
- put_help_line(" to the debugger.");
- put_help_line(" C-l Redraw the screen.");
- put_help_line(" ESC C-p <c> Goto pane whose name begins with <c>.");
- put_help_line(" C-x C-o Toggle between insert/overstrike mode.");
- put_help_line(" ");
- put_help_line("----------------------------------------------------------");
- put_help_line("MAIN MENU:");
- put_help_line(" ");
- put_help_line(" ESC ESC Quit main menu, go to previously active pane.");
- put_help_line(" C-g Quit main menu, go to previously active pane.");
- put_help_line(" f Select File pulldown.");
- put_help_line(" p Select Pane pulldown.");
- put_help_line(" l Select Local pulldown.");
- put_help_line(" m Select Miscellaneous pulldown.");
- put_help_line(" h Select Help pulldown.");
- put_help_line(" CR Select pulldown of highlighted choice.");
- put_help_line(" DN Select pulldown of highlighted choice.");
- put_help_line(" C-n Select pulldown of highlighted choice.");
- put_help_line(" C-f Highlight next choice on main menu.");
- put_help_line(" TAB Highlight next choice on main menu.");
- put_help_line(" RT Highlight next choice on main menu.");
- put_help_line(" C-b Highlight previous choice on main menu.");
- put_help_line(" S-TAB Highlight previous choice on main menu.");
- put_help_line(" LT Highlight previous choice on main menu.");
- put_help_line(" ");
- put_help_line("----------------------------------------------------------");
- put_help_line("PULLDOWNS:");
- put_help_line(" ");
- put_help_line(" ESC ESC Go to main menu.");
- put_help_line(" CR Select currently highlighted pulldown item.");
- put_help_line(" C-n Highlight next pulldown item.");
- put_help_line(" DN Highlight next pulldown item.");
- put_help_line(" C-p Highlight previous pulldown item.");
- put_help_line(" UP Highlight previous pulldown item.");
- put_help_line(" C-f Show pulldown of next main menu choice.");
- put_help_line(" RT Show pulldown of next main menu choice.");
- put_help_line(" TAB Show pulldown of next main menu choice.");
- put_help_line(" C-b Show pulldown of previous main menu choice.");
- put_help_line(" LT Show pulldown of previous main menu choice.");
- put_help_line(" S-TAB Show pulldown of previous main menu choice.");
- put_help_line(" ");
- put_help_line("----------------------------------------------------------");
- put_help_line("PANES:");
- put_help_line(" ");
- put_help_line(" ESC ESC Go to main menu.");
- put_help_line(" C-x o Go forward one pane.");
- put_help_line(" TAB Go forward one pane.");
- put_help_line(" S-TAB Go backward one pane.");
- put_help_line(" C-x C-x Go to previous pane (and again to return).");
- put_help_line(" C-x ^ Make current pane taller by one line.");
- put_help_line(" C-x } Make current pane wider by one line.");
- put_help_line(" C-x > Scroll text right (show more of the left).");
- put_help_line(" C-x < Scroll text left (show more of the right).");
- put_help_line(" C-f Move forward one line/byte/halfword/fullword.");
- put_help_line(" RT Move forward one line/byte/halfword/fullword.");
- put_help_line(" C-b Move backward one line/byte/halfword/fullword.");
- put_help_line(" LT Move backward one line/byte/halfword/fullword.");
- put_help_line(" C-n Move forward one line.");
- put_help_line(" DN Move forward one line.");
- put_help_line(" C-p Move backward one line.");
- put_help_line(" UP Move backward one line.");
- put_help_line(" C-v Move forward one page.");
- put_help_line(" PGDN Move forward one page.");
- put_help_line(" M-v Move backward one page.");
- put_help_line(" PGUP Move backward one page.");
- put_help_line(" M-< Move to beginning of pane.");
- put_help_line(" HOME Move to beginning of pane.");
- put_help_line(" M-> Move to end of pane.");
- put_help_line(" END Move to end of pane.");
- put_help_line(" ");
- put_help_line("----------------------------------------------------------");
- put_help_line("DIALOG BOXES:");
- put_help_line(" ");
- put_help_line(" ESC ESC Quit dialog box and discard any changes.");
- put_help_line(" C-g Quit dialog box and discard any changes.");
- put_help_line(" TAB Move to next field, if applicable.");
- put_help_line(" C-n Move to next field, if applicable.");
- put_help_line(" DN Move to next field, if applicable.");
- put_help_line(" S-TAB Move to previous field, if applicable.");
- put_help_line(" C-p Move to previous field, if applicable.");
- put_help_line(" UP Move to previous field, if applicable.");
- put_help_line(" CR Select highlighted item, if applicable.");
- put_help_line(" C-f Move forward one character, if applicable.");
- put_help_line(" RT Move forward one character, if applicable.");
- put_help_line(" C-b Move backward one character, if applicable.");
- put_help_line(" LT Move backward one character, if applicable.");
- put_help_line(" DEL Delete character left of cursor.");
- put_help_line(" C-d Delete character under cursor.");
- put_help_line(" CR Accept input and");
- put_help_line(" - go to next field (if not on a button), or");
- put_help_line(" - take action specified by button.");
- put_help_line(" ");
- put_help_line("----------------------------------------------------------");
- put_help_line("MINBUFFER:");
- put_help_line(" ");
- put_help_line(" ESC ESC Quit minibuffer and discard any changes.");
- put_help_line(" C-g Quit minibuffer and discard any changes.");
- put_help_line(" C-f Move forward one character, if applicable.");
- put_help_line(" RT Move forward one character, if applicable.");
- put_help_line(" C-b Move backward one character, if applicable.");
- put_help_line(" LT Move backward one character, if applicable.");
- put_help_line(" DEL Delete character left of cursor.");
- put_help_line(" C-d Delete character under cursor.");
- put_help_line(" CR Accept input.");
- put_help_line(" ");
- put_help_line("==========================================================");
- put_help_line(" PANE-SPECIFIC HELP");
- put_help_line("==========================================================");
- put_help_line("----------------------------------------------------------");
- put_help_line("HELP PANE:");
- put_help_line(" ");
- put_help_line(" CR Make code pane active.");
- put_help_line(" C-g Make code pane active.");
- put_help_line(" ");
- put_help_line("----------------------------------------------------------");
- put_help_line("CODE PANE:");
- put_help_line(" ");
- put_help_line(" s Single step, stepping over function calls.");
- put_help_line(" S Single step, stepping into function calls.");
- put_help_line(" C-c a Animate - run program by single stepping at");
- put_help_line(" a user-specified speed.");
- put_help_line(" b Toggle breakpoint on/off at current location.");
- put_help_line(" e Edit breakpoint via dialog box.");
- put_help_line(" Breakpoint particulars are:");
- put_help_line(" Address - breakpoint location.");
- put_help_line(" Type - 0 == Code breakpoint.");
- put_help_line(" 1 == Data write breakpoint.");
- put_help_line(" 2 == Data read breakpoint.");
- put_help_line(" Class - 0 == Always enabled.");
- put_help_line(" 1 == Breakpoint enabled only after");
- put_help_line(" being reached <count> times.");
- put_help_line(" 2 == Breakpoint enabled only after");
- put_help_line(" <condition> is true (nonzero).");
- put_help_line(" Count - Number of hits before a class 1");
- put_help_line(" breakpoint activates.");
- put_help_line(" Condition - Condition to be met before a");
- put_help_line(" class 2 breakpoint activates.");
- put_help_line(" The condition can be almost any");
- put_help_line(" C expression. For more info on");
- put_help_line(" allowable expressions, see the");
- put_help_line(" manual section on expressions.");
- put_help_line(" Two examples are:");
- put_help_line(" _Odd_num >> 3 == 1 && (_Even_num >> _Shift_val || _Test)");
- put_help_line(" (([%esi + %eax * 4] & 0x5fff) >> 12) & 0x0f == 4");
- put_help_line(" Size - The Size parameter allows you");
- put_help_line(" to specify the maximum size to");
- put_help_line(" be used during evaluation of");
- put_help_line(" expressions.");
- put_help_line(" C-c t Trace to current address. Same as toggling");
- put_help_line(" breakpoint, then running program.");
- put_help_line(" <n> CR Disassemble and display memory at specified");
- put_help_line(" decimal address.");
- put_help_line(" <x> CR Disassemble and display memory at specified");
- put_help_line(" hexadecimal address.");
- put_help_line(" _<sym> CR Disassemble and display memory at address");
- put_help_line(" specified by symbol <sym>.");
- put_help_line(" %<sym> CR Disassemble and display memory at address");
- put_help_line(" specified by value in register denoted by");
- put_help_line(" symbol <sym>.");
- put_help_line(" <exp> CR Disassemble and display memory at address");
- put_help_line(" specified by value of expression <exp>.");
- put_help_line(" i Disassemble and display memory at address");
- put_help_line(" specified by EIP (current run location).");
- put_help_line(" C-c i Set EIP to address of currently highlighted");
- put_help_line(" instruction.");
- put_help_line(" p Modify performance analyzer settings.");
- put_help_line(" C-c p Start performance analyzer and run program");
- put_help_line(" (if performance analyzer timer has been set).");
- put_help_line(" M-b Move pane's origin left by one byte.");
- put_help_line(" M-f Move pane's origin right by one byte.");
- put_help_line(" C-x / <c> Save highlighted location in debugger code");
- put_help_line(" pane register <c>.");
- put_help_line(" C-x j <c> Disassemble and display memory at location");
- put_help_line(" saved in debugger code pane register <c>.");
- put_help_line(" ");
- put_help_line("----------------------------------------------------------");
- put_help_line("DATA PANE:");
- put_help_line(" ");
- put_help_line(" w Toggle data write breakpoint on/off.");
- put_help_line(" r Toggle data read/write breakpoint on/off.");
- put_help_line(" e Edit data read or read/write breakpoint.");
- put_help_line(" Breakpoint particulars are:");
- put_help_line(" Address - breakpoint location.");
- put_help_line(" Type - 0 == Code breakpoint.");
- put_help_line(" 1 == Data write breakpoint.");
- put_help_line(" 2 == Data read breakpoint.");
- put_help_line(" Class - 0 == Always enabled.");
- put_help_line(" 1 == Breakpoint enabled only after");
- put_help_line(" being reached <count> times.");
- put_help_line(" 2 == Breakpoint enabled only after");
- put_help_line(" <condition> is true (nonzero).");
- put_help_line(" Count - Number of hits before a class 1");
- put_help_line(" breakpoint activates.");
- put_help_line(" Condition - Condition to be met before a");
- put_help_line(" class 2 breakpoint activates.");
- put_help_line(" The condition can be almost any");
- put_help_line(" C expression. For more info on");
- put_help_line(" allowable expressions, see the");
- put_help_line(" manual section on expressions.");
- put_help_line(" Two examples are:");
- put_help_line(" _Odd_num >> 3 == 1 && (_Even_num >> _Shift_val || _Test)");
- put_help_line(" (([%esi + %eax * 4] & 0x5fff) >> 12) & 0x0f == 4");
- put_help_line(" Size - The Size parameter allows you");
- put_help_line(" to specify the maximum size to");
- put_help_line(" be used during evaluation of");
- put_help_line(" expressions.");
- put_help_line(" b Display data in byte format.");
- put_help_line(" h Display data in halfword (two byte) format.");
- put_help_line(" f Display data in fullword (four byte) format.");
- put_help_line(" <n> CR Display memory at specified decimal address.");
- put_help_line(" <x> CR Display memory at specified hexadecimal");
- put_help_line(" address.");
- put_help_line(" _<sym> CR Display memory at address specified by");
- put_help_line(" symbol <sym>.");
- put_help_line(" %<sym> CR Display memory at address specified by value");
- put_help_line(" in register denoted by symbol <sym>.");
- put_help_line(" <exp> CR Display memory at address specified by value");
- put_help_line(" of expression <exp>.");
- put_help_line(" i Display memory at address specified by EIP");
- put_help_line(" (current run location).");
- put_help_line(" s Display memory at address specified by ESP");
- put_help_line(" (current stack pointer).");
- put_help_line(" * Dereference currently highlighted value.");
- put_help_line(" @ Retrace steps after a '*' command. Up to");
- put_help_line(" five (5) steps back are allowed.");
- put_help_line(" n Display data in customized format.");
- put_help_line(" p Input/output from/to ports as follows:");
- put_help_line(" Size - 1 = byte, 2 = word, 3 = dword");
- put_help_line(" b = byte, h = word, f = dword");
- put_help_line(" Port - port to access");
- put_help_line(" Data - data to write");
- put_help_line(" <In> button - input from port");
- put_help_line(" <Out> button - output to port");
- put_help_line(" M-b Move pane's origin left by one byte.");
- put_help_line(" M-f Move pane's origin right by one byte.");
- put_help_line(" C-c m Modify memory at cursor");
- put_help_line(" C-c u Undo last memory modification. No more than");
- put_help_line(" five (5) modifications can be undone.");
- put_help_line(" C-c s Search memory.");
- put_help_line(" C-x / <c> Save highlighted location in debugger data");
- put_help_line(" pane register <c>.");
- put_help_line(" C-x j <c> Display memory at location saved in");
- put_help_line(" debugger data pane register <c>.");
- put_help_line(" ");
- put_help_line("----------------------------------------------------------");
- put_help_line("REGISTERS PANE:");
- put_help_line(" ");
- put_help_line(" C-c m Modify register at cursor.");
- put_help_line(" C-c u Undo last register modification. No more");
- put_help_line(" than five (5) modifications can be undone.");
- put_help_line(" ");
- put_help_line("----------------------------------------------------------");
- put_help_line("FLAGS PANE:");
- put_help_line(" ");
- put_help_line(" All commands accessed via local menu.");
- put_help_line(" ");
- put_help_line("----------------------------------------------------------");
- put_help_line("BREAKPOINT PANE:");
- put_help_line(" ");
- put_help_line(" CR Goto location of currently highlighted");
- put_help_line(" breakpoint, in code or data pane, as");
- put_help_line(" appropriate.");
- put_help_line(" DEL Delete currently highlighted breakpoint.");
- put_help_line(" C-d Delete currently highlighted breakpoint.");
- put_help_line(" C-e Edit currently highlighted breakpoint.");
- put_help_line(" C-k Delete from currently highlighted breakpoint");
- put_help_line(" up to the last breakpoint.");
- put_help_line(" C-y Restore from previous deletion. No more");
- put_help_line(" than five (5) deletions can be undone.");
- put_help_line(" ");
- put_help_line("----------------------------------------------------------");
- put_help_line("WHEREIS PANE:");
- put_help_line(" ");
- put_help_line(" CR Display data/code at address represented by");
- put_help_line(" currently highlighted symbol.");
- put_help_line(" _<sym> CR Find <sym> in symbol table");
- put_help_line(" Permissible wildcards are:");
- put_help_line(" ? - Matches one character");
- put_help_line(" * - Matches any number of characters");
- put_help_line(" ");
- put_help_line("----------------------------------------------------------");
- put_help_line("MODULE PANE:");
- put_help_line(" ");
- put_help_line(" CR Prompt for a line number, disassemble and");
- put_help_line(" display code at that location.");
- put_help_line(" ");
- put_help_line("----------------------------------------------------------");
- put_help_line("NPX PANE: ");
- put_help_line(" ");
- put_help_line(" C-c e Empty register.");
- put_help_line(" C-c n Negate register contents.");
- put_help_line(" C-c z Zero register.");
- put_help_line(" C-c m Modify register contents.");
- put_help_line(" C-c u Undo last register modification. No more");
- put_help_line(" than five (5) modifications can be undone.");
- put_help_line(" ");
- put_help_line("----------------------------------------------------------");
- put_help_line("PERFORMANCE ANALYZER DATA VIEWER:");
- put_help_line(" ");
- put_help_line(" C-x C-w Log performance analyzer results to file.");
- put_help_line(" ");
- put_help_line("----------------------------------------------------------");
- put_help_line("STACK PANE:");
- put_help_line(" ");
- put_help_line(" CR Select highlighted location and display");
- put_help_line(" in data pane.");
- put_help_line(" ");
- put_help_line("----------------------------------------------------------");
- put_help_line("INFO PANE:");
- put_help_line(" ");
- put_help_line(" No commands available.");
- put_help_line(" ");
- put_help_line("==========================================================");
- put_help_line(" SYNTAX AND VALUES");
- put_help_line("==========================================================");
- put_help_line("----------------------------------------------------------");
- put_help_line("C EXPRESSIONS ALLOWED:");
- put_help_line(" ");
- put_help_line(" Syntax:");
- put_help_line(" <expr> = <l_exp> [<l_op> <l_exp> ...]");
- put_help_line(" <l_exp> = <a_exp> [<r_op> <a_exp> ...] | ");
- put_help_line(" (<l_exp>) | !<l_exp>");
- put_help_line(" <a_exp> = <a_exp>|<identifier> [<a_op> ");
- put_help_line(" <a_exp>|<identifier> ...] | (<a_exp>)");
- put_help_line(" <identifier> = <identifier> | <[<a_exp>]><size>");
- put_help_line(" where");
- put_help_line(" <l_exp> is a logical expression.");
- put_help_line(" <l_op> is one of: && ||");
- put_help_line(" <a_exp> is an arithmetic expression");
- put_help_line(" <r_op> is one of: < <= == != >= >");
- put_help_line(" <a_op> is one of: + - * / >> << & | ! ~");
- put_help_line(" <identifier> is an identifiler (a symbol, register) ");
- put_help_line(" a number, or a memory reference.");
- put_help_line(" ");
- put_help_line(" * <identifier> can be a global variable name,");
- put_help_line(" symbolic constant, constant value, register name,");
- put_help_line(" or memory reference (i.e. an expression which");
- put_help_line(" evaluates to a memory location).");
- put_help_line(" * All register names must begin with a '%' (percent) ");
- put_help_line(" character. ");
- put_help_line(" * All memory references have the structure: ");
- put_help_line(" [<address expression>]size ");
- put_help_line(" where size can be b, h, f, or nothing.");
- put_help_line(" b: 1 byte. h: 2 bytes. f: 4 bytes. Any other");
- put_help_line(" character immediately following the right square ");
- put_help_line(" bracket (]) and is not one of the above characters");
- put_help_line(" will be interpreted as part of the expression.");
- put_help_line(" By default (if neither b, h, or f follows the");
- put_help_line(" right square bracket,) the reference will read");
- put_help_line(" 4 bytes from memory.");
- put_help_line(" * When constructing expressions, be aware that");
- put_help_line(" the modulo (%) operator is not allowed, since");
- put_help_line(" it conficts with the register naming scheme.");
- put_help_line(" To perform a modulo, use divide (/) and");
- put_help_line(" subtract (-): (a % b) == (a - a / b)");
- put_help_line(" * When constructing expressions, be wary");
- put_help_line(" of possible overflow (the debugger uses");
- put_help_line(" 32 bit arithmetic to evaluate expressions).");
- put_help_line(" ");
- put_help_line(" Examples of valid expressions: ");
- put_help_line(" ");
- put_help_line(" _Odd_num >> 3 == 1 && (_Even_num >> _Shift_val || _Test)");
- put_help_line(" (([%esi + %eax * 4] & 0x5fff) >> 12) & 0x0f == 4 ");
- put_help_line(" ");
- put_help_line("----------------------------------------------------------");
- put_help_line("REMOTE DEBUGGING DEVICES");
- put_help_line(" ");
- put_help_line(" con : console. ");
- put_help_line(" com_one : COM1. ");
- put_help_line(" com_two : COM2. ");
- put_help_line(" com_three : COM3. ");
- put_help_line(" com_four : COM4. ");
- put_help_line(" ");
- put_help_line("==========================================================");
- }
- /* ---------------------------------------------------------------------- */
- static void
- initialize (void)
- { int i;
-
- using_com_port_num = remote;
- init_io (using_com_port_num);
- if (_go32_info_block.run_mode != _GO32_RUN_MODE_DPMI)
- test_npx ();
-
- debug_screen_p = 0;
- toplines = (rows / 2) + 4;
- bottomlines = rows - 4 - toplines;
- main_x1 = cols - 18;
- main_x2 = cols - 5;
- main_x3 = 46;
-
- code_pane_pos = malloc ((rows + 2) * sizeof (word32));
- stack_dump_pos = malloc ((rows + 2) * sizeof (word32));
-
- debug_screen_save = get_screen ();
- debug_screen_save[1] = debug_screen_save[2] = 0; /* Patch cursor pos. */
-
- pane = 10;
- pane_pos = 0;
- for (i = 0; i < PANECOUNT; i++) pane_positions[i] = 0;
- data_dump_origin = areas[A_data].first_addr;
- data_dump_size = 1;
- code_dump_origin = a_tss.tss_eip;
- stack_dump_origin = 0;
- breakpoint_origin = 0;
- breakpoint_count = 0;
- breakpoint_table = malloc (breakpoint_count * sizeof (BP_ENTRY));
- whereis_origin = 0;
- whereis_sym_count = 0;
- whereis_pane_sym = malloc (whereis_sym_count * sizeof (char *));
- module_origin = 0;
- module_text_count = 0;
- module_pane_text = malloc (module_text_count * sizeof (char *));
- init_module ();
- help_origin = 0;
- help_text_count = 0;
- help_pane_text = malloc (help_text_count * sizeof (char *));
- init_help();
- flag_pane_origin = 0;
- reg_pane_origin = 0;
- help_pane_active = 1;
- npx_pane_active = stack_pane_active = info_pane_active
- = whereis_pane_active = module_pane_active
- = code_pane_active = 0;
- sprintf (active_pane_name, "Help Pane");
-
- init_eval_data (0, 0); /* Force to calculate addresses */
- init_undo (&data_undo, free_do_nothing);
- init_undo (®ister_undo, free_do_nothing);
- init_undo (&npx_undo, free_npx);
- init_undo (&breakpoint_undo, free_breakpoint);
-
- redraw (1);
- message (CL_Info, "Ladybug version %d.%02d", MAJOR_VER, MINOR_VER);
- }
- /* ---------------------------------------------------------------------- */
- static void
- view_eval_data (void)
- {
- EVAL_SEG_INFO swap_data;
- EVAL_DATA_TABLE temp_data;
- int i, j, percent_bar;
- long percent;
- int32 delta;
- word32 total_hits = 0, in_hits = 0, out_hits;
- char *save, *name = alloca (256), *name2 = alloca (256), *p;
-
- if (total_hits_count == 0)
- { message (CL_Error,
- "Nothing has been recorded, cannot calculate percentage");
- return;
- }
-
- for (i = 0; i < EVAL_SEGMENTS; i++)
- { temp_data[i].start_addr = evaluation_data[i].start_addr;
- temp_data[i].stop_addr = evaluation_data[i].stop_addr;
- temp_data[i].hits_count = evaluation_data[i].hits_count;
- total_hits += temp_data[i].hits_count;
- }
-
- for (i = 0; i < EVAL_SEGMENTS - 1; i++)
- for (j = i + 1; j < EVAL_SEGMENTS; j++)
- if (temp_data[i].hits_count < temp_data[j].hits_count)
- { swap_data.start_addr = temp_data[i].start_addr;
- swap_data.stop_addr = temp_data[i].stop_addr;
- swap_data.hits_count = temp_data[i].hits_count;
-
- temp_data[i].start_addr = temp_data[j].start_addr;
- temp_data[i].stop_addr = temp_data[j].stop_addr;
- temp_data[i].hits_count = temp_data[j].hits_count;
-
- temp_data[j].start_addr = swap_data.start_addr;
- temp_data[j].stop_addr = swap_data.stop_addr;
- temp_data[j].hits_count = swap_data.hits_count;
- }
- j = (rows / 2) - 4;
- save = debug_screen_save;
- debug_screen_save = get_screen ();
- screen_attr = screen_attr_normal;
- clear_screen ();
- screen_attr = screen_attr_ffocus;
- double_frame (0, 0, cols - 1, rows - 1, "Performance Analyzer's Result");
- screen_attr = screen_attr_normal;
-
- sprintf (name, "Most called segments (from %08lx to %08lx)",
- evaluation_data[0].start_addr,
- evaluation_data[EVAL_SEGMENTS - 1].stop_addr);
- putl (cols / 2 - 24, 1, 50, name);
- for (i = 0; i < j; i++)
- in_hits += temp_data[i].hits_count;
-
- if (in_hits == 0)
- putl (2, 3, cols-5, "Nothing is recorded inside the given addresses.");
- else
- { for (i = 0; i < j; i++)
- {
- percent = (long)temp_data[i].hits_count;
- percent *= 100;
-
- p = syms_val2name (temp_data[i].start_addr, &delta);
- if (p[0] != '0')
- if (delta)
- sprintf (name, "(%s+%#lx)", p, delta);
- else
- sprintf (name, "(%s)",p);
- else
- sprintf(name, "(No Symbols");
- p = syms_val2name (temp_data[i].stop_addr, &delta);
- if (p[0] != '0')
- if (delta)
- sprintf (name2, "(%s+%#lx)", p, delta);
- else
- sprintf (name2, "(%s)", p);
- else
- sprintf(name2, "No Symbols)");
-
- sprintf (read_buffer, "%02ld.%-1ld%% %08lx-%08lx %s-%s",
- percent / total_hits, ((percent % total_hits) * 10) / total_hits,
- temp_data[i].start_addr, temp_data[i].stop_addr,
- name, name2);
- percent /= 100;
- percent_bar = percent * (cols - 5) / total_hits;
-
- putl (2, i * 2 + 3, cols - 4, read_buffer);
- draw (2, i * 2 + 4, '-', 1, percent_bar);
- }
-
- out_hits = total_hits - in_hits;
- percent = out_hits * 100;
-
- sprintf (name, "%02ld.%-1ld%% : Other segments (%% of total in-range hits)",
- percent / total_hits, ((percent % total_hits) * 10) / total_hits);
- putl (2, i * 2 + 3, cols - 4, name);
- percent /= 100;
- percent_bar = percent * (cols - 5) / in_hits;
- draw (2, i * 2 + 4, '-', 1, percent_bar);
- i++;
- }
- out_hits = total_hits_count - total_hits;
- percent = out_hits * 100;
-
- sprintf (name, "%02ld.%-1ld%% : Outside of defined range (over total of %010ld)",
- percent / total_hits_count,
- ((percent % total_hits_count) * 10) / total_hits_count,
- total_hits_count);
- putl (2, i * 2 + 3, cols - 4, name);
- percent /= 100;
- percent_bar = percent * (cols - 5) / total_hits_count;
- draw (2, i * 2 + 4, '-', 1, percent_bar);
-
- put_screen (debug_screen_save);
- do
- { i = getykey ();
- if (i == K_Control_X)
- { i = getykey ();
- if (i == K_Control_W)
- { write_log (1, 1, cols - 1, rows - 1);
- i = 0;
- }
- }
- } while (i == 0);
- free (debug_screen_save);
- debug_screen_save = save;
- put_screen (debug_screen_save);
- }
- /* ---------------------------------------------------------------------- */
- static void
- init_time (char *output, char *input, word32 addr)
- { sprintf (output, "%s", *(int *)addr ? "On " : "Off");
- }
- /* ---------------------------------------------------------------------- */
- static int
- edtime (char *text, word32 addr, int x, int y, int len, int *key)
- { if (*key == K_Return) /* Only enter toggles timer */
- { if (*(int *)addr)
- reset_timer ();
- else
- set_timer ();
- }
- *key = 0;
- return 1;
- }
- /* ---------------------------------------------------------------------- */
- static int
- action_init (DIALOG_ITEM dialog_data[])
- { word32 start_addr = 0, stop_addr = 0;
- int ok;
-
- if (!my_read_string ("Enter start address: "))
- start_addr = parse_expression(4, read_buffer, &ok);
- if (ok != ParseError_ok)
- { message (CL_Error, "Bad address: %s", read_buffer);
- return (0);
- }
- if (!my_read_string ("Enter stop address: "))
- stop_addr = parse_expression(4, read_buffer, &ok);
- if (ok != ParseError_ok)
- { message (CL_Error, "Bad address: %s", read_buffer);
- return (0);
- }
- init_eval_data (start_addr, stop_addr);
- return (1);
- }
- /* ---------------------------------------------------------------------- */
- static int
- action_view (DIALOG_ITEM dialog_data[])
- { view_eval_data ();
- return (1);
- }
- /* ---------------------------------------------------------------------- */
- static void
- evaluation_dialogue (void)
- { int ret = 0;
- static DIALOG_ITEM dialog_data[] = {
- {"Timer :", 0 , 03, 1, format_asis, eval_asis, init_time, edtime},
- {"Segments :", 0 , 05, 0, format_int , eval_word, init_int , editor},
- {0 , 0 , 0 , 0, 0 , 0 , 0 , 0 }
- };
- static BUTTON_ITEM button_data[] = {
- {" ReInit ", 1, action_init},
- {" View ", 1, action_view},
- {" Done ", 0, action_done},
- {0 , 0, 0 }
- };
- dialog_data[0].return_addr = (word32)&timer_is_set;
- dialog_data[1].return_addr = (word32)&total_segments;
- dialog ("P.A. Settings", dialog_data, button_data, &ret);
- }
- /* ---------------------------------------------------------------------- */
- static MENU_ITEM Code_Local_Menu[] = {
- {"Current Highlighted Item ", 1 , "" , 0},
- {"Run ~^R~", ITEM_TYPE, "\022" , 0},
- {"Step into function ~S~", ITEM_TYPE, "S" , 0},
- {"Step over function ~s~", ITEM_TYPE, "s" , 0},
- {"Trace to current address ~^C t~", ITEM_TYPE, "\3t" , 0},
- {"Animate ~^C a~", ITEM_TYPE, "\3a" , 0},
- {"Toggle breakpoint ~b~", ITEM_TYPE, "b" , 0},
- {"Toggle/edit breakpoint ~e~", ITEM_TYPE, "e" , 0},
- {"Perfomance analyzer settings ~p~", ITEM_TYPE, "p" , 0},
- {"Start performance analyzer ~^C p~", ITEM_TYPE, "\3p" , 0},
- {"Display code at EIP ~i~", ITEM_TYPE, "i" , 0},
- {"Set EIP to current address ~^C i~", ITEM_TYPE, "\3i" , 0},
- {"Move pane's origin left one byte ~M b~", ITEM_TYPE, "\033b", 0},
- {"Move pane's origin right one byte ~M f~", ITEM_TYPE, "\033f", 0},
- {0 , 0 , "" , 0}
- };
- /* ---------------------------------------------------------------------- */
- static void
- code_pane_command (int key)
- { int b;
-
- if (key == 0)
- { pop_menu (Code_Local_Menu, "Code", 1, 3, &b);
- control_c = 0;
- control_x = 0;
- escaped = 0;
- switch (b)
- { case 1:
- step (2); /* Run is a global command... */
- break;
- case 2:
- key = 'S';
- break;
- case 3:
- key = 's';
- break;
- case 4:
- control_c = 1;
- key = 't';
- break;
- case 5:
- control_c = 1;
- key = 'a';
- break;
- case 6:
- key = 'b';
- break;
- case 7:
- key = 'e';
- break;
- case 8:
- key = 'p';
- break;
- case 9:
- control_c = 1;
- key = 'p';
- break;
- case 10:
- key = 'i';
- break;
- case 11:
- control_c = 1;
- key = 'i';
- break;
- case 12:
- escaped = 1;
- key = 'b';
- break;
- case 13:
- escaped = 1;
- key = 'f';
- break;
- }
- }
- if (control_c)
- { switch (key)
- { case 'a': /* Animate */
- if (using_com_port_num)
- { message (CL_Error, "Local mode only.");
- break;
- }
- if (!my_read_string("Time between step (tens of msecs): "))
- { unsigned long milisec;
- char *endp;
- int stopped = 0;
-
- milisec = strtoul(read_buffer, &endp, 10);
- if (milisec > 0)
- while (!stopped)
- { step(0);
- stopped = short_sleep(milisec);
- }
- }
- break;
- case 't': /* Trace */
- b = set_breakpoint (BP_Code, 0, code_pane_pos[pane_pos]);
- step (2);
- reset_breakpoint (b);
- break;
- case 'i': /* Set EIP to current */
- a_tss.tss_eip = code_pane_pos[pane_pos];
- break;
- case 'p': /* Start perfom. analyzer*/
- if (timer_is_set)
- { start_evaluate ();
- step (2);
- stop_evaluate ();
- reset_timer ();
- } else
- message (CL_Error, "Timer has not been set -- Action aborted.");
- break;
- }
- }
- if (control_x)
- { switch (key)
- { case '/': /* Save to register */
- key = my_get_char ("Save address to which register (0..A..z)? ");
- if (key >= '0' && key <= 'z')
- registers[key - '0'] = code_pane_pos[pane_pos];
- break;
- case 'j': /* Load from register */
- case 'J':
- key = my_get_char ("Load address from which register (0..A..z)? ");
- if (key >= '0' && key <= 'z')
- if (registers[key - '0'])
- code_pane_goto (registers[key - '0']);
- break;
- }
- }
- if (escaped)
- { switch (key)
- { case 'b': /* Move origin left */
- case 'B':
- code_dump_origin--;
- break;
- case 'f': /* Move origin right */
- case 'F':
- code_dump_origin++;
- break;
- case 'v': /* PageUp */
- case 'V':
- escaped = 0;
- key = K_PageUp;
- break;
- }
- }
- if (!(control_c || control_x || escaped))
- { switch (key)
- { case K_Up:
- case K_EUp:
- case K_Control_B:
- case K_Control_P:
- if (pane_pos > 0)
- pane_pos--;
- else
- code_pane_goto (code_skip (code_dump_origin, -1));
- break;
- case K_Down:
- case K_EDown:
- case K_Control_F:
- case K_Control_N:
- if (pane_pos < toplines - 2)
- pane_pos++;
- else
- code_dump_origin =
- code_pane_pos[0] == code_pane_pos[1]
- ? code_pane_pos[2] : code_pane_pos[1];
- break;
- case K_PageUp:
- case K_EPageUp:
- code_dump_origin = code_skip (code_dump_origin, 2 - toplines);
- break;
- case K_PageDown:
- case K_EPageDown:
- case K_Control_V:
- code_dump_origin = code_dump_last + 1;
- break;
- case 'b':
- case 'B':
- b = get_breakpoint (BP_Code, -1, code_pane_pos[pane_pos]);
- if (b != -1)
- reset_breakpoint (b);
- else
- b = set_breakpoint (BP_Code, 4, code_pane_pos[pane_pos]);
- break;
- case 'e':
- case 'E':
- b = get_breakpoint (BP_Code, -1, code_pane_pos[pane_pos]);
- if (b == -1)
- { b = set_breakpoint (BP_Code, 4, code_pane_pos[pane_pos]);
- if (edit_breakpoint(b))
- reset_breakpoint (b);
- } else
- edit_breakpoint (b);
- break;
- case 'i':
- case 'I':
- code_pane_goto (a_tss.tss_eip);
- break;
- case 'p':
- case 'P':
- evaluation_dialogue ();
- break;
- case 's':
- step (1);
- break;
- case 'S':
- step (0);
- break;
- default:
- if ((key == '_') || (key == '%') ||
- (key == '(') || (key >= '0' && key <= '9'))
- { int res, ok;
- char s[2], *p;
-
- s[0] = key; s[1] = '\0';
- if (last_addr[0])
- ok = !read_string (last_addr);
- else
- ok = !read_string (key == '=' ? "" : s);
- strcpy (last_addr, read_buffer);
- p = read_buffer;
- while (*p != 0 && *p == ' ')
- p++;
- if (*p)
- { if (ok)
- { res = parse_expression (4, read_buffer, &ok);
- if (ok == ParseError_ok)
- { message (CL_Info, "Found address %s.", read_buffer);
- code_pane_goto (res);
- last_addr[0] = 0;
- }
- else
- message (CL_Error, "Bad address: %s", read_buffer);
- }
- }
- }
- break;
- }
- }
- redraw (0);
- }
- /* ---------------------------------------------------------------------- */
- static MENU_ITEM Register_Local_Menu[] = {
- {"Current Highlighted Item ", 1 , "" , 0},
- {"Modify current register ~^C m~", ITEM_TYPE, "\3m", 0},
- {"Undo last modification ~^C u~", ITEM_TYPE, "\3u", 0},
- {0 , 0 , "" , 0}
- };
- /* ---------------------------------------------------------------------- */
- static void
- register_pane_command (int key)
- { int curr = pane_pos + reg_pane_origin;
- int b;
-
- if (key == 0)
- { pop_menu (Register_Local_Menu, "Registers", cols - 33, 3, &b);
- switch (b)
- { case 1:
- control_c = 1;
- key = 'm';
- break;
- case 2:
- control_c = 1;
- key = 'u';
- break;
- }
- }
- if (control_c)
- { switch (key)
- { case 'm':
- case 'M':
- { int res, ok;
- if (!my_read_string ("New value: ") && read_buffer[0])
- { res = parse_expression (4, read_buffer, &ok);
- if (ok == ParseError_ok)
- switch (regs_type[curr])
- { case 's':
- put_undo (®ister_undo, (word32)(regs_addr[curr]),
- *regs_addr[curr], 2);
- *(unsigned short *)(regs_addr[curr]) = res & 0xffff;
- break;
- case 'f':
- put_undo (®ister_undo, 0,
- a_tss.tss_eflags, 0);
- a_tss.tss_eflags = (a_tss.tss_eflags & ~0xed5) | (res & 0xed5);
- break;
- default:
- put_undo (®ister_undo, (word32)(regs_addr[curr]),
- *regs_addr[curr], 4);
- *regs_addr[curr] = res;
- }
- else message (CL_Error, "Bad expression: %s", read_buffer);
- }
- break;
- }
- case 'u':
- case 'U':
- { word32 u_addr, u_val;
- int u_size;
-
- if (get_undo (®ister_undo, &u_addr, &u_val, &u_size))
- { switch (u_size)
- { case 2: /* 's' */
- *(unsigned short *)(u_addr) = u_val & 0xffff;
- break;
- case 0: /* 'f' */
- a_tss.tss_eflags = (a_tss.tss_eflags & ~0xed5) | (u_val & 0xed5);
- break;
- case 4:
- *(word32 *)u_addr = u_val;
- break;
- }
- }
- break;
- }
- }
- }
- if (!(escaped || control_c || control_x))
- switch (key)
- { case K_Left:
- case K_ELeft:
- case K_Up:
- case K_EUp:
- case K_Control_P:
- case K_Control_B:
- if (pane_pos > 0)
- pane_pos--;
- else if (reg_pane_origin)
- reg_pane_origin--;
- break;
- case K_Right:
- case K_ERight:
- case K_Down:
- case K_EDown:
- case K_Control_N:
- case K_Control_F:
- if (regs_type[pane_pos + reg_pane_origin + 1])
- if (pane_pos < toplines - 2)
- pane_pos++;
- else
- reg_pane_origin++;
- break;
- }
- redraw (0);
- }
- /* ---------------------------------------------------------------------- */
- static MENU_ITEM Flag_Local_Menu[] = {
- {"Current ", 1 , "" , 0},
- {"~T~oggle flag", ITEM_TYPE, "t", 0},
- {"~S~et flag ", ITEM_TYPE, "s", 0},
- {"~R~eset flag ", ITEM_TYPE, "r", 0},
- {0 , 0 , "" , 0}
- };
- /* ---------------------------------------------------------------------- */
- static void
- flag_pane_command (int key)
- { static unsigned flagbits[] =
- { 0x0001, 0x0004, 0x0010, 0x0040, 0x0080, 0x0200, 0x0400, 0x0800 };
- int b, curr = pane_pos + flag_pane_origin;
-
- if (key == 0)
- { pop_menu (Flag_Local_Menu, "Flag", cols - 20, 3, &b);
- switch (b)
- { case 1:
- a_tss.tss_eflags ^= flagbits[curr];
- break;
- case 2:
- a_tss.tss_eflags |= flagbits[curr];
- break;
- case 3:
- a_tss.tss_eflags &= ~flagbits[curr];
- break;
- }
- }
- if (!(escaped || control_c || control_x))
- switch (key)
- { case K_Left:
- case K_ELeft:
- case K_Up:
- case K_EUp:
- case K_Control_P:
- case K_Control_B:
- if (pane_pos > 0)
- pane_pos--;
- else if (flag_pane_origin)
- flag_pane_origin--;
- break;
- case K_Right:
- case K_ERight:
- case K_Down:
- case K_EDown:
- case K_Control_N:
- case K_Control_F:
- if (curr < 7)
- if (pane_pos < toplines - 2)
- pane_pos++;
- else
- flag_pane_origin++;
- break;
- }
- redraw (0);
- }
- /* ---------------------------------------------------------------------- */
- static MENU_ITEM Breakpoint_Local_Menu[] = {
- {"Current Highlighted Item ", 1 , "" , 0},
- {"Delete breakpoint ~^D~", ITEM_TYPE, "\4" , 0},
- {"Edit breakpoint ~^E~", ITEM_TYPE, "\5" , 0},
- {"Display Breakpoint ", ITEM_TYPE, "" , 0},
- {"Clear from current breakpoint ~^K~", ITEM_TYPE, "\013", 0},
- {"Restore breakpoint(s) ~^Y~", ITEM_TYPE, "\031", 0},
- {0 , 0 , "" , 0}
- };
- /* ---------------------------------------------------------------------- */
- static void
- breakpoint_pane_command (int key)
- {
- int b = breakpoint_count ? pane_pos + breakpoint_origin : -1;
- int last = breakpoint_count && (b == breakpoint_count - 1);
- BP_ENTRY *del_bp;
-
- if (key == 0)
- { pop_menu (Breakpoint_Local_Menu, "Breakpoint", cols - 40, rows - 15, &b);
- control_c = 0;
- control_x = 0;
- escaped = 0;
- switch (b)
- { case 1:
- key = K_Control_D;
- break;
- case 2:
- key = K_Control_E;
- break;
- case 3:
- key = K_Return;
- break;
- case 4:
- key = K_Control_K;
- break;
- case 5:
- key = K_Control_Y;
- break;
- }
- }
- b = breakpoint_count ? pane_pos + breakpoint_origin : -1;
- if (!(escaped || control_c || control_x))
- switch (key)
- { case K_Delete:
- case K_EDelete:
- case K_Control_D:
- if (b != -1)
- reset_breakpoint (b);
- if (!last)
- break;
- /* else fall through */
- case K_Left:
- case K_ELeft:
- case K_Up:
- case K_EUp:
- case K_Control_P:
- case K_Control_B:
- if (pane_pos > 0)
- pane_pos--;
- else
- if (breakpoint_origin > 0)
- breakpoint_origin--;
- break;
- case K_Right:
- case K_ERight:
- case K_Down:
- case K_EDown:
- case K_Control_N:
- case K_Control_F:
- if (!last)
- if (pane_pos < bottomlines / 2 - 1)
- pane_pos++;
- else
- breakpoint_origin++;
- break;
- case K_Return:
- if (b != -1)
- if (breakpoint_table[b].type == BP_Code)
- code_pane_goto (breakpoint_table[b].addr);
- else
- data_dump_origin = breakpoint_table[b].addr;
- break;
- case K_Control_E:
- if (b != -1)
- edit_breakpoint(b);
- break;
- case K_Control_K:
- { int temp = breakpoint_count - 1;
- if (b >= 0)
- while (temp >= b)
- reset_breakpoint (temp--);
- break;
- }
- case K_Control_Y:
- { word32 u_addr, u_val;
- int u_size;
-
- if (get_undo (&breakpoint_undo, &u_addr, &u_val, &u_size))
- { del_bp = (BP_ENTRY *)u_val;
- b = set_breakpoint (del_bp->type, del_bp->length, del_bp->addr);
- breakpoint_table[b].sub_type = del_bp->sub_type;
- breakpoint_table[b].count = del_bp->count;
- strcpy (breakpoint_table[b].condition, del_bp->condition);
- free (del_bp);
- }
- break;
- }
- }
- redraw (0);
- }
- /* ---------------------------------------------------------------------- */
- static int
- action_search (DIALOG_ITEM dialog_data[])
- { int size = *(int *)(dialog_data[0].return_addr);
- word32 start_at = *(word32 *)(dialog_data[1].return_addr);
- word32 search_for = *(word32 *)(dialog_data[2].return_addr);
- word8 search_byte, *mem_byte;
- word16 search_word, *mem_word;
- word32 stop_at, *mem_long;
- int i, buf_size, found = 0;
-
- stop_at = start_at;
- if (!size || !valid_addr (start_at, size))
- return (0);
- for (i = 0; i < MAX_AREA && !found; i++)
- if (start_at + size <= areas[i].last_addr &&
- start_at >= areas[i].first_addr)
- { stop_at = areas[i].last_addr;
- found = 1;
- }
- if (!found && start_at + size <= dos_mem_hi && start_at >= dos_mem_lo)
- { stop_at = dos_mem_hi;
- found = 1;
- }
- if (!found)
- return (0);
- found = 0;
- switch (size)
- { case 1:
- search_byte = (word8)(search_for & 0xff);
- do
- { if (stop_at < start_at + size)
- break;
- buf_size = stop_at - start_at;
- if (buf_size > 4096)
- buf_size = 4096;
- read_child (start_at, read_buffer, buf_size);
- mem_byte = (word8 *)read_buffer;
- for (i = 0; i < buf_size; i++)
- if (mem_byte[i] == search_byte)
- { found = 1;
- start_at += i;
- break;
- }
- if (!found)
- start_at += 4096;
- } while (!found);
- break;
- case 2:
- search_word = (word16)(search_for & 0xffff);
- do
- { if (stop_at < start_at + size)
- break;
- buf_size = stop_at - start_at;
- if (buf_size > 4096)
- buf_size = 4096;
- read_child (start_at, read_buffer, buf_size);
- buf_size /= 2;
- mem_word = (word16 *)read_buffer;
- for (i = 0; i < buf_size; i++)
- if (mem_word[i] == search_word)
- { found = 1;
- start_at += i * 2;
- break;
- }
- if (!found)
- start_at += 4096;
- } while (!found);
- break;
- default:
- size = 4;
- do
- { if (stop_at < start_at + size)
- break;
- buf_size = stop_at - start_at;
- if (buf_size > 4096)
- buf_size = 4096;
- read_child (start_at, read_buffer, buf_size);
- buf_size /= 4;
- mem_long = (word32 *)read_buffer;
- for (i = 0; i < buf_size; i++)
- if (mem_long[i] == search_for)
- { found = 1;
- start_at += i * 4;
- break;
- }
- if (!found)
- start_at += 4096;
- } while (!found);
- break;
- }
- if (!found)
- return (0);
- *(word32 *)(dialog_data[1].return_addr) = start_at + size;
- *(word32 *)(dialog_data[0].return_addr) = size;
- data_dump_origin = start_at;
- pane_pos = 0;
- redraw (0);
- return (1);
- }
- /* ---------------------------------------------------------------------- */
- static void
- search_memory (void)
- { int size = 1, ret = 2;
- word32 start_at = areas[A_data].first_addr, search_for = 0;
-
- static DIALOG_ITEM dialog_data[] = {
- {"Size :", 0 , 03, 1, format_int , eval_word, init_int , editor},
- {"Start at :", 0 , 50, 1, format_addr, eval_word, init_addr, editor},
- {"Search for :", 0 , 10, 1, format_word, eval_word, init_word, editor},
- {0 , 0 , 0 , 0, 0 , 0 , 0 , 0 }
- };
- static BUTTON_ITEM button_data[] = {
- {" Search ", 1, action_search},
- {" Done ", 0, action_done },
- {0 , 0, 0 }
- };
-
- dialog_data[0].return_addr = (word32)&size;
- dialog_data[1].return_addr = (word32)&start_at;
- dialog_data[2].return_addr = (word32)&search_for;
- dialog ("Memory Search", dialog_data, button_data, &ret);
- }
- /* ---------------------------------------------------------------------- */
- static void
- port_io_add_action (DIALOG_ITEM d[], int action,
- word32 port, word32 size, word32 data)
- { unsigned char action_id, *p, fmt[ACTION_HIST_SIZE];
- memcpy ((char *)(d[1].return_addr), (char *)(d[2].return_addr), ACTION_HIST_SIZE);
- memcpy ((char *)(d[2].return_addr), (char *)(d[3].return_addr), ACTION_HIST_SIZE);
- memcpy ((char *)(d[3].return_addr), (char *)(d[4].return_addr), ACTION_HIST_SIZE);
- memcpy ((char *)(d[4].return_addr), (char *)(d[5].return_addr), ACTION_HIST_SIZE);
- p = (char *)(d[5].return_addr);
- action_id = p[strlen (p) + 1];
- action_id++;
- sprintf (fmt, "%%03d %%s 0x%%04lx%%-%lds0x%%0%ldlx", 9 - size * 2, size * 2);
- sprintf (p, fmt, action_id, action ? "Out" : " In", port, " ", data);
- p[strlen (p) + 1] = action_id;
- }
- /* ---------------------------------------------------------------------- */
- static int
- action_outp (DIALOG_ITEM dialog_data[])
- { int size = *(int *)(dialog_data[6].return_addr);
- word32 port = *(word32 *)(dialog_data[7].return_addr);
- word32 data = *(word32 *)(dialog_data[8].return_addr);
-
- port &= 0xffff;
- if (!port || !size)
- return (0);
- switch (size)
- { case 2:
- data &= 0xffff;
- outportw (port, data);
- break;
- case 4:
- outportl (port, data);
- break;
- default:
- data &= 0xff;
- outportb (port, data);
- break;
- }
- port_io_add_action (dialog_data, 1, port, size, data);
- return (1);
- }
- /* ---------------------------------------------------------------------- */
- static int
- action_inp (DIALOG_ITEM dialog_data[])
- { int size = *(int *)(dialog_data[6].return_addr);
- word32 port = *(word32 *)(dialog_data[7].return_addr);
- word32 data;
-
- port &= 0xffff;
- if (!port || !size)
- return (0);
- switch (size)
- { case 2:
- data = inportw (port) & 0xffff;
- break;
- case 4:
- data = inportl (port);
- break;
- default:
- *(int *)(dialog_data[6].return_addr) = 1;
- size = 1;
- data = inportb (port) & 0xff;
- break;
- }
- *(word32 *)(dialog_data[8].return_addr) = data;
- port_io_add_action (dialog_data, 0, port, size, data);
- return (1);
- }
- /* ---------------------------------------------------------------------- */
- static void
- read_write_port (void)
- { int ret = 11;
- static int size = 1;
- static word32 port = 0x20, data = 0;
- static char last_act_0[ACTION_HIST_SIZE] = " ID Action Port Value";
- static char last_act_1[ACTION_HIST_SIZE] = "--- --- ------ ----------\0";
- static char last_act_2[ACTION_HIST_SIZE] = "--- --- ------ ----------\0";
- static char last_act_3[ACTION_HIST_SIZE] = "--- --- ------ ----------\0";
- static char last_act_4[ACTION_HIST_SIZE] = "--- --- ------ ----------\0";
- static char last_act_5[ACTION_HIST_SIZE] = "--- --- ------ ----------\0\377";
-
- static DIALOG_ITEM dialog_data[] = {
- {"History:", 0, 60, 0, format_asis, eval_asis, init_asis, editor},
- {" ", 0, 60, 0, format_asis, eval_asis, init_asis, editor},
- {" ", 0, 60, 0, format_asis, eval_asis, init_asis, editor},
- {" ", 0, 60, 0, format_asis, eval_asis, init_asis, editor},
- {" ", 0, 60, 0, format_asis, eval_asis, init_asis, editor},
- {" ", 0, 60, 0, format_asis, eval_asis, init_asis, editor},
- {"Size :", 0, 03, 1, format_int , eval_word, init_int , editor},
- {"Port :", 0, 10, 1, format_word, eval_word, init_word, editor},
- {"Data :", 0, 10, 1, format_word, eval_word, init_word, editor},
- {0 , 0, 0 , 0, 0 , 0 , 0 , 0 }
- };
- static BUTTON_ITEM button_data[] = {
- {" Out ", 1, action_outp},
- {" In ", 1, action_inp },
- {" Done ", 0, action_done},
- {0 , 0, 0 }
- };
-
- dialog_data[0].return_addr = (word32)last_act_0;
- dialog_data[1].return_addr = (word32)last_act_1;
- dialog_data[2].return_addr = (word32)last_act_2;
- dialog_data[3].return_addr = (word32)last_act_3;
- dialog_data[4].return_addr = (word32)last_act_4;
- dialog_data[5].return_addr = (word32)last_act_5;
- dialog_data[6].return_addr = (word32)&size;
- dialog_data[7].return_addr = (word32)&port;
- dialog_data[8].return_addr = (word32)&data;
- dialog ("Port IO", dialog_data, button_data, &ret);
- }
- /* ---------------------------------------------------------------------- */
- static MENU_ITEM Data_Local_Menu[] = {
- {"Current Highlighted Item ", 1 , "" , 0},
- {"Toggle data write breakpoint ~w~", ITEM_TYPE, "w" , 0},
- {"Toggle read/write breakpoint ~r~", ITEM_TYPE, "r" , 0},
- {"Display data at EIP ~i~", ITEM_TYPE, "i" , 0},
- {"Display data at ESP ~s~", ITEM_TYPE, "s" , 0},
- {"Display data at current pointer ~*~", ITEM_TYPE, "*" , 0},
- {"Display data at last address(es) ~@~", ITEM_TYPE, "@" , 0},
- {"Move pane's origin left ~M b~", ITEM_TYPE, "\033b", 0},
- {"Move pane's origin right ~M f~", ITEM_TYPE, "\033f", 0},
- {"Display as bytes ~b~", ITEM_TYPE, "b" , 0},
- {"Display as words ~h~", ITEM_TYPE, "h" , 0},
- {"Display as dwords ~f~", ITEM_TYPE, "f" , 0},
- {"Port access ~p~", ITEM_TYPE, "p" , 0},
- {"Modify data at cursor ~^C m~", ITEM_TYPE, "\3m" , 0},
- {"Undo modification(s) ~^C u~", ITEM_TYPE, "\3u" , 0},
- {"Search memory ~^C s~", ITEM_TYPE, "\3s" , 0},
- {"Data structure supports ~n~", ITEM_TYPE, "n" , 0},
- {0 , 0 , "" , 0}
- };
- static word32 old_dump_address[5] = {0, 0, 0, 0, 0};
- /* ---------------------------------------------------------------------- */
- static void
- data_pane_command (int key)
- { word32 v = data_dump_origin + pane_pos;
- int res, ok, bad = 0;
- char *p, *p0, q, s[2];
-
- if (key == 0)
- { pop_menu (Data_Local_Menu, "Data", 1, rows - 19, &res);
- control_c = 0;
- control_x = 0;
- escaped = 0;
- switch (res)
- { case 1:
- key = 'w';
- break;
- case 2:
- key = 'r';
- break;
- case 3:
- key = 'i';
- break;
- case 4:
- key = 's';
- break;
- case 5:
- key = '*';
- break;
- case 6:
- key = '@';
- break;
- case 7:
- escaped = 1;
- key = 'b';
- break;
- case 8:
- escaped = 1;
- key = 'f';
- break;
- case 9:
- key = 'b';
- break;
- case 10:
- key = 'h';
- break;
- case 11:
- key = 'f';
- break;
- case 12:
- key = 'p';
- break;
- case 13:
- control_c = 1;
- key = 'm';
- break;
- case 14:
- control_c = 1;
- key = 'u';
- break;
- case 15:
- control_c = 1;
- key = 's';
- case 16:
- key = 'n';
- break;
- }
- }
- if (control_x)
- { switch (key)
- { case '/': /* Save to register */
- key = my_get_char ("Save address to which register (0..A..z)? ");
- if (key >= '0' && key <= 'z')
- registers[key - '0'] = v;
- break;
- case 'j': /* Load from register */
- case 'J':
- key = my_get_char ("Load address from which register (0..A..z)? ");
- if (key >= '0' && key <= 'z')
- if (registers[key - '0'])
- { data_dump_origin = registers[key - '0'];
- pane_pos = 0;
- }
- break;
- }
- }
- if (control_c)
- { switch (key)
- { case 'm':
- case 'M':
- { if (!my_read_string ("New value: "))
- { p = read_buffer;
- do
- { while (*p == ' ') p++;
- switch (*p)
- { case '\0':
- break;
- case '\'':
- case '"':
- if (data_dump_size != 1)
- { *p = 0;
- message (CL_Error, "Strings must be entered in byte mode");
- break;
- }
- q = *p++;
- p0 = p;
- while (*p != q && *p)
- p++;
- if (*p)
- { while (p0 != p)
- { if (valid_addr (v, 1))
- write_child (v, p0, 1);
- else
- bad = 1;
- p0++, v++;
- }
- if (q == '"')
- { if (valid_addr (v, 1))
- { q = 0;
- write_child (v, &q, 1);
- q = '"';
- }
- else
- bad = 1;
- v++;
- }
- p++;
- }
- else
- message (CL_Error, "String constant not terminated");
- break;
- default:
- p0 = p;
- while (*p != ',' && *p)
- p++;
- q = *p;
- *p = 0;
- res = parse_expression (4, p0, &ok);
- if (ok == ParseError_ok)
- { *p = q;
- if (valid_addr (v, data_dump_size))
- { word32 u_val;
- read_child (v, &u_val, data_dump_size);
- put_undo (&data_undo, v, u_val, data_dump_size);
- write_child (v, &res, data_dump_size);
- } else
- bad = 1;
- v += data_dump_size;
- } else
- { message (CL_Error, "Invalid expression: %s", p0);
- bad = 1;
- }
- }
- if (*p == ',')
- p++;
- } while (*p);
- if (bad)
- message (CL_Error, "Part of the data could not be written");
- else
- message (CL_Info, "Memory modified.");
- }
- break;
- }
- case 'u':
- case 'U':
- { word32 u_addr, u_val, old_val = 0;
- int u_size;
-
- if (get_undo (&data_undo, &u_addr, &u_val, &u_size))
- { read_child (u_addr, &old_val, u_size);
- write_child (u_addr, &u_val, u_size);
- message (CL_Msg,
- "%d byte(s) at %08lx has been undone from %08lx to %08lx",
- u_size, u_addr, old_val, u_val);
- }
- break;
- }
- case 's':
- case 'S':
- search_memory ();
- break;
- }
- }
- if (escaped)
- { switch (key)
- { case 'b':
- case 'B':
- data_dump_origin--;
- break;
- case 'f':
- case 'F':
- data_dump_origin++;
- break;
- case 'v':
- case 'V':
- escaped = 0;
- key = K_PageUp;
- break;
- }
- }
- if (!(escaped || control_c || control_x))
- switch (key)
- { case K_Up:
- case K_EUp:
- case K_Control_P:
- if (pane_pos >= 8)
- pane_pos -= 8;
- else
- data_dump_origin -= 8;
- break;
- case K_Down:
- case K_EDown:
- case K_Control_N:
- if (v + 8 <= data_dump_last)
- pane_pos += 8;
- else
- data_dump_origin += 8;
- break;
- case K_Left:
- case K_ELeft:
- case K_Control_B:
- if (pane_pos > 0)
- pane_pos -= data_dump_size;
- else
- data_dump_origin -= 8, pane_pos = 8 - data_dump_size;
- break;
- case K_Right:
- case K_ERight:
- case K_Control_F:
- if (v + data_dump_size <= data_dump_last)
- pane_pos += data_dump_size;
- else
- data_dump_origin += 8, pane_pos -= (8 - data_dump_size);
- break;
- case K_PageUp:
- case K_EPageUp:
- data_dump_origin -= (data_dump_last + 1 - data_dump_origin);
- break;
- case K_PageDown:
- case K_EPageDown:
- case K_Control_V:
- data_dump_origin = data_dump_last + 1;
- break;
- case 's':
- case 'S':
- data_dump_origin = a_tss.tss_esp;
- pane_pos = 0;
- break;
- case 'i':
- case 'I':
- data_dump_origin = a_tss.tss_eip;
- data_dump_size = 1;
- pane_pos = 0;
- break;
- case '*':
- if (valid_addr (v, 4))
- { for (res = 1; res < 5; res++)
- old_dump_address[res - 1] = old_dump_address[res];
- old_dump_address[4] = data_dump_origin + pane_pos;
- read_child (v, &data_dump_origin, 4);
- pane_pos = 0;
- } else
- message (CL_Error, "Pointer points to an invalid address.");
- break;
- case '@':
- if (!old_dump_address[4])
- old_dump_address[4] = data_dump_origin;
- data_dump_origin = old_dump_address[4];
- pane_pos = 0;
- for (res = 4; res > 0; res--)
- old_dump_address[res] = old_dump_address[res - 1];
- old_dump_address[0] = data_dump_origin;
- break;
- case 'b':
- case 'B':
- data_dump_size = 1;
- break;
- case 'h':
- case 'H':
- data_dump_size = 2;
- break;
- case 'f':
- case 'F':
- data_dump_size = 4;
- break;
- case 'n':
- case 'N':
- if (!running_xsupport)
- { running_xsupport = 1;
- if (extern_data_support(v))
- running_xsupport = 0;
- break;
- }
- case 'p':
- case 'P':
- read_write_port();
- break;
- case 'w':
- case 'W':
- res = get_breakpoint (BP_Write, data_dump_size, v);
- if (res == -1)
- set_breakpoint (BP_Write, data_dump_size, v);
- else
- reset_breakpoint (res);
- break;
- case 'r':
- case 'R':
- res = get_breakpoint (BP_Read, data_dump_size, v);
- if (res == -1)
- set_breakpoint (BP_Read, data_dump_size, v);
- else
- reset_breakpoint (res);
- break;
- case 'e':
- case 'E':
- res = get_breakpoint (BP_Read, -1, v);
- if (res == -1)
- { res = set_breakpoint (BP_Read, data_dump_size, v);
- if (edit_breakpoint(res))
- reset_breakpoint (res);
- } else
- edit_breakpoint (res);
- break;
- default:
- if ((key == '_') || (key == '%') ||
- (key == '(') || (key >= '0' && key <= '9'))
- { s[0] = key; s[1] = '\0';
- if (last_addr[0])
- ok = !read_string (last_addr);
- else
- ok = !read_string (key == '=' ? "" : s);
- strcpy (last_addr, read_buffer);
- if (ok)
- { p = read_buffer;
- while (*p != 0 && *p == ' ')
- p++;
- if (*p)
- { res = parse_expression (4, p, &ok);
- if (ok == ParseError_ok)
- { data_dump_origin = res;
- pane_pos = 0;
- for (res = 1; res < 5; res++)
- old_dump_address[res - 1] = old_dump_address[res];
- old_dump_address[4] = data_dump_origin;
- last_addr[0] = 0;
- message (CL_Info, "Found address %s.", p);
- }
- else
- message (CL_Error, "Bad address: %s", p);
- }
- }
- }
- break;
- }
- pane_pos &= ~(data_dump_size - 1);
- redraw (0);
- }
- /* ---------------------------------------------------------------------- */
- static MENU_ITEM Npx_Local_Menu[] = {
- {"Current Item ", 1 , "" , 0},
- {"Empty register ~^C e~", ITEM_TYPE, "\3e", 0},
- {"Zero register ~^C z~", ITEM_TYPE, "\3z", 0},
- {"Negate register ~^C n~", ITEM_TYPE, "\3n", 0},
- {"Modify register ~^C m~", ITEM_TYPE, "\3m", 0},
- {"Undo modification ~^C u~", ITEM_TYPE, "\3u", 0},
- {0 , 0 , "" , 0}
- };
- /* ---------------------------------------------------------------------- */
- static void
- npx_pane_command (int key)
- { NPX *del_npx;
- int reg = pane_pos - 3, rotreg = 0, tag = 0;
- int regp = (reg >= 0);
- int b;
-
- save_npx ();
- if (regp)
- { rotreg = (reg + (npx.status >> 11)) & 7;
- tag = (npx.tag >> (rotreg * 2)) & 3;
- }
-
- if (key == 0)
- { pop_menu (Npx_Local_Menu, "Npx", 1, 3, &b);
- control_c = 1;
- control_x = 0;
- escaped = 0;
- switch (b)
- { case 1:
- key = 'e';
- break;
- case 2:
- key = 'z';
- break;
- case 3:
- key = 'n';
- break;
- case 4:
- key = 'm';
- break;
- case 5:
- key = 'u';
- break;
- }
- }
- if (control_c)
- { switch (key)
- { case 'e':
- case 'E':
- if (regp)
- { tag = 3;
- del_npx = malloc (sizeof (NPX));
- memcpy (del_npx, &npx, sizeof (NPX));
- put_undo (&npx_undo, 1, (word32)del_npx, 1);
- memset (&npx.reg[reg], 0, sizeof (NPXREG));
- }
- break;
- case 'z':
- case 'Z':
- if (regp)
- { tag = 1;
- del_npx = malloc (sizeof (NPX));
- memcpy (del_npx, &npx, sizeof (NPX));
- put_undo (&npx_undo, 1, (word32)del_npx, 1);
- memset (&npx.reg[reg], 0, sizeof (NPXREG));
- }
- break;
- case 'n':
- case 'N':
- if (regp)
- { del_npx = malloc (sizeof (NPX));
- memcpy (del_npx, &npx, sizeof (NPX));
- put_undo (&npx_undo, 1, (word32)del_npx, 1);
- npx.reg[reg].sign = !npx.reg[reg].sign;
- }
- break;
- case 'm':
- case 'M':
- { char *p, *endp;
- double d;
-
- if (!my_read_string ("New value: "))
- { p = read_buffer;
- del_npx = malloc (sizeof (NPX));
- memcpy (del_npx, &npx, sizeof (NPX));
- put_undo (&npx_undo, 1, (word32)del_npx, 1);
- while (*p == ' ')
- p++;
- if (*p == '\0')
- break;
- strlwr (p);
- if (strcmp (p, "+inf") == 0
- || strcmp (p, "inf") == 0
- || strcmp (p, "-inf") == 0)
- { tag = 2;
- npx.reg[reg].exponent = 0x7fff;
- npx.reg[reg].sig3 = 0x8000;
- npx.reg[reg].sig2
- = npx.reg[reg].sig1
- = npx.reg[reg].sig0 = 0;
- npx.reg[reg].sign = (*p == '-');
- } else
- { d = strtod (p, &endp);
- if (*p != '\0' && *endp)
- message (CL_Error, "Expression not understood");
- else
- { tag = (d == 0.0);
- *((long double *)(npx.reg + reg)) = (long double) d;
- npx.reg[reg].sign = (*p == '-'); /* for -Zero */
- }
- }
- }
- break;
- }
- case 'u':
- case 'U':
- { word32 u_addr, u_val;
- int u_size;
- if (get_undo (&npx_undo, &u_addr, &u_val, &u_size))
- { del_npx = (NPX *)u_val;
- memcpy (&npx, del_npx, sizeof (NPX));
- }
- break;
- }
- }
- }
- if (!(escaped || control_c || control_x))
- switch (key)
- { case K_Left:
- case K_ELeft:
- case K_Up:
- case K_EUp:
- case K_Control_P:
- case K_Control_B:
- if (pane_pos > 0) pane_pos--;
- break;
- case K_Right:
- case K_ERight:
- case K_Down:
- case K_EDown:
- case K_Control_N:
- case K_Control_F:
- if ((pane_pos < 10) && (pane_pos < toplines - 2)) pane_pos++;
- break;
- }
- if (regp)
- npx.tag = (npx.tag & ~(3 << (rotreg * 2))) | (tag << (rotreg * 2));
- load_npx ();
- redraw (0);
- }
- /* ---------------------------------------------------------------------- */
- static MENU_ITEM Stack_Local_Menu[] = {
- {"Current Highlighted", 1 , "" , 0},
- {"Goto function ~^M~", ITEM_TYPE, "\015", 0},
- {0 , 0 , "" , 0}
- };
- /* ---------------------------------------------------------------------- */
- static void
- stack_pane_command (int key)
- {
- int b;
-
- if (key == 0)
- { pop_menu (Stack_Local_Menu, "Stack", 1, 3, &b);
- control_c = 0;
- control_x = 0;
- escaped = 0;
- switch (b)
- { case 1:
- key = K_Return;
- break;
- }
- }
- if (!(escaped || control_c || control_x))
- switch (key)
- { case K_Left:
- case K_ELeft:
- case K_Up:
- case K_EUp:
- case K_Control_P:
- case K_Control_B:
- if (pane_pos > 0)
- pane_pos--;
- else
- if (stack_dump_origin)
- stack_dump_origin--;
- break;
- case K_Right:
- case K_ERight:
- case K_Down:
- case K_EDown:
- case K_Control_N:
- case K_Control_F:
- if (pane_pos < stack_dump_last)
- pane_pos++;
- else
- if (stack_dump_more)
- stack_dump_origin++;
- break;
- case K_Return:
- code_pane_goto (stack_dump_pos[pane_pos]);
- stack_pane_active = 0;
- code_pane_active = 1;
- pane = 0;
- break;
- }
- redraw (0);
- }
- /* ---------------------------------------------------------------------- */
- static MENU_ITEM Info_Local_Menu[] = {
- {"Current Highlighted Item", 1 , "", 0},
- {"No command available ", ITEM_TYPE, "", 0},
- {0 , 0 , "", 0}
- };
- /* ---------------------------------------------------------------------- */
- static void
- info_pane_command (int key)
- { int b;
- /* No keys recognized. */
-
- if (key == 0)
- { pop_menu (Info_Local_Menu, "Info", 1, 3, &b);
- }
- redraw (0);
- }
- /* ---------------------------------------------------------------------- */
- static void
- fullscr_listwild_handler (word32 sym_num)
- { whereis_pane_sym = realloc (whereis_pane_sym,
- (++whereis_sym_count) * sizeof (word32));
- whereis_pane_sym[whereis_sym_count - 1] = sym_num;
- }
- /* ---------------------------------------------------------------------- */
- static void
- init_whereis_sym (void)
- { char *p;
-
- if (!my_read_string ("Search for: ") && read_buffer[0] != '\0')
- { whereis_pane_sym = realloc (whereis_pane_sym, 0);
- p = read_buffer;
- while (*p == ' ') p++;
- syms_listwild (p, &fullscr_listwild_handler);
- pane_pos = whereis_origin = 0;
- if (whereis_sym_count >= 10)
- message (CL_Info, "There were %d symbols that matched",
- whereis_sym_count);
- }
- redraw (0);
- }
- /* ---------------------------------------------------------------------- */
- static MENU_ITEM WhereIs_Local_Menu[] = {
- {"Current Highlighted Item ", 1 , "" , 0},
- {"Goto beginning of list ~M <~", ITEM_TYPE, "\033<", 0},
- {"Goto end of list ~M >~", ITEM_TYPE, "\033>", 0},
- {"Search for symbol(s) ", ITEM_TYPE, "" , 0},
- {0 , 0 , "" , 0}
- };
- /* ---------------------------------------------------------------------- */
- static void
- whereis_pane_command (int key)
- {
- int no = whereis_origin + pane_pos;
- int b;
-
- if (key == 0)
- { pop_menu (WhereIs_Local_Menu, "WhereIs", 1, 3, &b);
- control_c = 0;
- control_x = 0;
- escaped = 0;
- switch (b)
- { case 1:
- key = K_Home;
- break;
- case 2:
- key = K_End;
- break;
- case 3:
- key = '_';
- break;
- }
- }
- if (escaped)
- { switch (key)
- { case 'v':
- case 'V':
- escaped = 0;
- key = K_PageUp;
- break;
- case '>':
- escaped = 0;
- key = K_End;
- break;
- case '<':
- escaped = 0;
- key = K_Home;
- break;
- }
- }
- if (!(escaped || control_c || control_x))
- { switch (key)
- { case K_Left:
- case K_ELeft:
- case K_Up:
- case K_EUp:
- case K_Control_P:
- case K_Control_B:
- if (pane_pos > 0)
- pane_pos--;
- else
- if (whereis_origin)
- whereis_origin--;
- break;
- case K_Right:
- case K_ERight:
- case K_Down:
- case K_EDown:
- case K_Control_N:
- case K_Control_F:
- if (no < whereis_sym_count - 1)
- if (pane_pos < toplines - 2)
- pane_pos++;
- else
- whereis_origin++;
- break;
- case K_Home:
- case K_EHome:
- pane_pos = whereis_origin = 0;
- break;
- case K_End:
- case K_EEnd:
- if (whereis_sym_count > toplines - 1)
- { whereis_origin = whereis_sym_count - toplines;
- pane_pos = toplines - 2;
- }
- else
- { whereis_origin = 0;
- pane_pos = whereis_sym_count ? whereis_sym_count - 1 : 0;
- }
- break;
- case K_PageDown:
- case K_EPageDown:
- case K_Control_V:
- if (whereis_origin + toplines < whereis_sym_count)
- { whereis_origin += toplines - 1;
- if (whereis_origin + pane_pos >= whereis_sym_count)
- pane_pos = whereis_sym_count - 1 - whereis_origin;
- }
- break;
- case K_PageUp:
- case K_EPageUp:
- if (whereis_origin > toplines)
- whereis_origin -= toplines;
- else
- whereis_origin = pane_pos = 0;
- break;
- case K_Return:
- if (whereis_sym_count)
- { char typ;
- unsigned long ul;
-
- syms_get (whereis_pane_sym[no], &ul, &typ);
- switch (toupper (typ))
- { case 'T':
- code_pane_goto (ul);
- whereis_pane_active = 0;
- code_pane_active = 1;
- pane = 0;
- break;
- case 'B':
- case 'D':
- data_dump_origin = ul;
- pane_positions[4] = 0;
- break;
- }
- }
- break;
- default:
- if ((key == '_') || (key >= '0' && key <= '9'))
- { char s[2], *p;
-
- s[0] = key; s[1] = '\0';
- if (!read_string (key == '=' ? "" : s) && read_buffer[0] != '\0')
- { whereis_pane_sym = realloc (whereis_pane_sym, 0);
- whereis_sym_count = 0;
- p = read_buffer;
- while (*p == ' ') p++;
- syms_listwild (p, &fullscr_listwild_handler);
- pane_pos = whereis_origin = 0;
- if (whereis_sym_count >= 10)
- message (CL_Info, "There were %d symbols that matched",
- whereis_sym_count);
- }
- }
- }
- }
- redraw (0);
- }
- /* ---------------------------------------------------------------------- */
- static MENU_ITEM Module_Local_Menu[] = {
- {"Current Highlighted Item", 1 , "", 0},
- {"No command available ", ITEM_TYPE, "", 0},
- {0 , 0 , "", 0}
- };
- /* ---------------------------------------------------------------------- */
- static void
- module_pane_command(int key)
- {
- int no = module_origin + pane_pos;
- int b;
-
- if (key == 0)
- { pop_menu (Module_Local_Menu, "Module", 1, 3, &b);
- }
- if (escaped)
- { switch (key)
- { case 'v':
- case 'V':
- escaped = 0;
- key = K_PageUp;
- break;
- case '>':
- escaped = 0;
- key = K_End;
- break;
- case '<':
- escaped = 0;
- key = K_Home;
- break;
- }
- }
- if (!(escaped || control_c || control_x))
- { switch (key)
- { case K_Left:
- case K_ELeft:
- case K_Up:
- case K_EUp:
- if (pane_pos > 0)
- pane_pos--;
- else
- if (module_origin)
- module_origin--;
- break;
- case K_Right:
- case K_ERight:
- case K_Down:
- case K_EDown:
- if (no < module_text_count - 1)
- if (pane_pos < toplines - 2)
- pane_pos++;
- else
- module_origin++;
- break;
- case K_Home:
- case K_EHome:
- pane_pos = module_origin = 0;
- break;
- case K_End:
- case K_EEnd:
- if (module_text_count > toplines - 1)
- { module_origin = module_text_count - toplines;
- pane_pos = toplines - 2;
- }
- else
- { module_origin = 0;
- pane_pos = module_text_count ? module_text_count - 1 : 0;
- }
- break;
- case K_PageDown:
- case K_EPageDown:
- case K_Control_V:
- if (module_origin + toplines <= module_text_count)
- { module_origin += toplines - 1;
- if (module_origin + pane_pos >= module_text_count)
- pane_pos = module_text_count - 1 - module_origin;
- }
- break;
- case K_PageUp:
- case K_EPageUp:
- if (module_origin > toplines - 1)
- module_origin -= toplines - 1;
- else
- module_origin = pane_pos = 0;
- break;
- case K_Return:
- if (no)
- if (!my_read_string ("Line number: "))
- { unsigned long ul;
- char *endp;
-
- ul = strtoul (read_buffer, &endp, 0);
- ul = get_linenum (no - 1, ul);
- code_pane_goto (ul);
- module_pane_active = 0;
- code_pane_active = 1;
- pane = 0;
- }
- break;
- case K_Control_G:
- module_pane_active = 0;
- code_pane_active = 1;
- pane = 0;
- break;
- }
- }
- redraw (0);
- }
- /* ---------------------------------------------------------------------- */
- static MENU_ITEM Help_Local_Menu[] = {
- {"Current Highlighted Item", 1 , "", 0},
- {"No command available ", ITEM_TYPE, "", 0},
- {0 , 0 , "", 0}
- };
- /* ---------------------------------------------------------------------- */
- static void
- help_pane_command(int key)
- {
- int no = help_origin + pane_pos;
- int b;
-
- if (key == 0)
- { pop_menu (Help_Local_Menu, "Help", 1, 3, &b);
- }
- if (escaped)
- { switch (key)
- { case 'v':
- case 'V':
- escaped = 0;
- key = K_PageUp;
- break;
- case '>':
- escaped = 0;
- key = K_End;
- break;
- case '<':
- escaped = 0;
- key = K_Home;
- break;
- }
- }
- if (!(escaped || control_c || control_x))
- { switch (key)
- { case K_Left:
- case K_ELeft:
- case K_Up:
- case K_EUp:
- case K_Control_P:
- case K_Control_B:
- if (pane_pos > 0)
- pane_pos--;
- else
- if (help_origin)
- help_origin--;
- break;
- case K_Right:
- case K_ERight:
- case K_Down:
- case K_EDown:
- case K_Control_N:
- case K_Control_F:
- if (no < help_text_count - 1)
- if (pane_pos < toplines - 2)
- pane_pos++;
- else
- help_origin++;
- break;
- case K_Home:
- case K_EHome:
- pane_pos = help_origin = 0;
- break;
- case K_End:
- case K_EEnd:
- if (help_text_count > toplines - 1)
- { help_origin = help_text_count - toplines;
- pane_pos = toplines - 2;
- }
- else
- { help_origin = 0;
- pane_pos = help_text_count ? help_text_count - 1 : 0;
- }
- break;
- case K_PageDown:
- case K_EPageDown:
- case K_Control_V:
- if (help_origin + toplines <= help_text_count)
- { help_origin += toplines;
- if (help_origin + pane_pos >= help_text_count)
- pane_pos = help_text_count - 1 - help_origin;
- }
- break;
- case K_PageUp:
- case K_EPageUp:
- if (help_origin > toplines - 1)
- help_origin -= toplines - 1;
- else
- help_origin = pane_pos = 0;
- break;
- case K_Return:
- case K_Control_G:
- case K_Space:
- help_pane_active = 0;
- code_pane_active = 1;
- pane = 0;
- break;
- }
- }
- redraw (0);
- }
- /* ---------------------------------------------------------------------- */
- static void
- view_regs (void)
- { WIN_TEXT read_text;
- char *p;
- int i;
-
- init_text (&read_text, "Address Registers");
- p = malloc (max_cols + 5);
- for (i = 0; i < MAX_REGISTERS; i++)
- { sprintf (p, "Register[%c] == %08lx", i + '0', registers[i]);
- add_text (&read_text, p);
- }
- free (p);
- text_win (read_text, 40, 20);
- free_text (&read_text);
- }
- /* ---------------------------------------------------------------------- */
- static void
- resize_screen(void)
- { int key, i;
-
- while (1)
- { redraw(-1);
- key = getykey();
- if (key == K_Escape)
- { key = getykey ();
- if (key == K_Escape)
- key = K_Control_G;
- }
- switch (key)
- { case K_Up:
- case K_EUp:
- case K_Control_P:
- if (toplines > 3)
- { toplines--;
- bottomlines++;
- }
- break;
- case K_Down:
- case K_EDown:
- case K_Control_N:
- if (toplines < rows - 4)
- { toplines++;
- bottomlines--;
- }
- break;
- case K_Left:
- case K_ELeft:
- case K_Control_B:
- switch (pane)
- { case 1: /* Top middle */
- case 2: /* Top right */
- if ((main_x2 > 3) && (main_x2 - main_x1 > 3))
- main_x2--;
- break;
- case 3: /* Bottom right */
- case 4: /* Bottom left */
- if (main_x3 > 11 + 2 * data_dump_size)
- main_x3--;
- break;
- default: /* Top left */
- if (main_x1 > 3)
- main_x1--;
- break;
- }
- break;
- case K_Right:
- case K_ERight:
- case K_Control_F:
- switch (pane)
- { case 1: /* Top middle */
- case 2: /* Top right */
- if (main_x2 < cols - 4)
- main_x2++;
- break;
- case 3: /* Bottom right */
- case 4: /* Bottom left */
- if (main_x3 < cols - 4)
- main_x3++;
- break;
- default: /* Top left */
- if ((main_x1 < cols - 4) && (main_x2 - main_x1 > 3))
- main_x1++;
- break;
- }
- break;
- }
- if (key == K_Return)
- break;
- if (key == K_Control_G)
- break;
- }
- for (i = 0; i < PANECOUNT; i++)
- switch(i)
- { case 3: /* Bottom panes */
- case 4:
- if (pane_positions[i] > bottomlines - 1)
- pane_positions[i] = bottomlines - 1;
- break;
- default: /* Top panes */
- if (pane_positions[i] > toplines - 1)
- pane_positions[i] = toplines - 1;
- break;
- }
- switch(pane)
- { case 3: /* Bottom panes */
- case 4:
- if (pane_pos > bottomlines - 1)
- pane_pos = bottomlines - 1;
- break;
- default: /* Top panes */
- if (pane_pos > toplines - 1)
- pane_pos = toplines - 1;
- break;
- }
- redraw(0);
- }
- /* ---------------------------------------------------------------------- */
- static void
- setup_io(void)
- {
- if (!my_read_string("Redirect IO to device: "))
- {
- if (strncmp (read_buffer, "con", 3) == 0)
- using_com_port_num = 0;
- if (strncmp (read_buffer, "com_one", 7) == 0)
- using_com_port_num = 1;
- if (strncmp (read_buffer, "com_two", 7) == 0)
- using_com_port_num = 2;
- if (strncmp (read_buffer, "com_three", 9) == 0)
- using_com_port_num = 3;
- if (strncmp (read_buffer, "com_four", 8) == 0)
- using_com_port_num = 4;
- if (using_com_port_num)
- { re_init_io (using_com_port_num, rows, cols);
- toplines = (rows / 2) + 4;
- bottomlines = rows - 3 - toplines;
- main_x1 = cols - 18;
- main_x2 = cols - 5;
- main_x3 = 46;
- }
- free (code_pane_pos);
- free (stack_dump_pos);
- code_pane_pos = malloc ((rows + 2) * sizeof (word32));
- stack_dump_pos = malloc ((rows + 2) * sizeof (word32));
- free (debug_screen_save);
- free (user_screen_save);
- debug_screen_save = get_screen ();
- debug_screen_save[1] = debug_screen_save[2] = 0;
- user_screen_save = get_screen ();
- user_screen_save[1] = debug_screen_save[2] = 0;
- }
- redraw (0);
- }
- /* ---------------------------------------------------------------------- */
- static void
- setup_screen(void)
- {
- int new_cols, new_rows;
-
- if (!my_read_string("Columns: "))
- {
- char *endp;
-
- new_cols = strtoul(read_buffer, &endp, 10);
- if (new_cols == 0)
- new_cols = cols;
- }
- else
- new_cols = cols;
-
- if (new_cols < 20)
- new_cols = 20;
- if (new_cols > max_cols)
- new_cols = max_cols;
-
- if (!my_read_string("Rows: "))
- {
- char *endp;
-
- new_rows = strtoul(read_buffer, &endp, 10);
- if (new_rows == 0)
- new_rows = rows;
- }
- else
- new_rows = rows;
-
- if (new_rows < 15)
- new_rows = 15;
- if (new_rows > max_rows)
- new_rows = max_rows;
-
- re_init_io (using_com_port_num, new_rows, new_cols);
-
- toplines = (rows / 2) + 4;
- bottomlines = rows - 3 - toplines;
- main_x1 = cols - 18;
- main_x2 = cols - 5;
- main_x3 = 46;
- if (main_x3 > cols)
- main_x3 = cols - 10;
-
- free (code_pane_pos);
- free (stack_dump_pos);
-
- code_pane_pos = malloc ((rows + 2) * sizeof (word32));
- stack_dump_pos = malloc ((rows + 2) * sizeof (word32));
-
- free (debug_screen_save);
- debug_screen_save = get_screen ();
- debug_screen_save[1] = debug_screen_save[2] = 0; /* Patch cursor pos. */
-
- redraw (0);
- }
- /* ---------------------------------------------------------------------- */
- static void
- make_pane_name (void)
- { switch (pane)
- { case CODE_PANE_NUM:
- sprintf (active_pane_name, "Code Pane");
- break;
- case NPX_PANE_NUM:
- sprintf (active_pane_name, "NPX Pane");
- break;
- case STACK_PANE_NUM:
- sprintf (active_pane_name, "Stack Pane");
- break;
- case INFO_PANE_NUM:
- sprintf (active_pane_name, "Info Pane");
- break;
- case WHEREIS_PANE_NUM:
- sprintf (active_pane_name, "WhereIs Pane");
- break;
- case MODULE_PANE_NUM:
- sprintf (active_pane_name, "Module Pane");
- break;
- case HELP_PANE_NUM:
- sprintf (active_pane_name, "Help Pane");
- break;
- }
- }
- /* ---------------------------------------------------------------------- */
- static int
- make_pane_from_key (int key)
- { switch (key)
- { case 'B':
- case 'b':
- return (203);
- break;
- case 'C':
- case 'c':
- return (204);
- break;
- case 'D':
- case 'd':
- return (205);
- break;
- case 'F':
- case 'f':
- return (206);
- break;
- case 'H':
- case 'h':
- return (207);
- break;
- case 'I':
- case 'i':
- return (208);
- break;
- case 'M':
- case 'm':
- return (209);
- break;
- case 'N':
- case 'n':
- return (210);
- break;
- case 'R':
- case 'r':
- return (211);
- break;
- case 'S':
- case 's':
- return (212);
- break;
- case 'W':
- case 'w':
- return (213);
- break;
- default:
- return (999);
- break;
- }
- }
- /* ---------------------------------------------------------------------- */
- static void
- log_current_pane (void)
- { switch (pane) /* focused pane */
- { case 1: /* Top middle */
- write_log (main_x1 + 1, 2, main_x2, toplines + 1);
- break;
- case 2: /* Top right */
- write_log (main_x2 + 1, 2, cols - 1, toplines + 1);
- break;
- case 3: /* Bottom right */
- write_log (main_x3+1, toplines+2, cols-1, rows-1);
- break;
- case 4: /* Bottom left */
- write_log (1, toplines + 2, main_x3, rows - 1);
- break;
- default: /* Top Left */
- write_log (1, 2, main_x1, toplines + 1);
- break;
- }
- }
- /* ---------------------------------------------------------------------- */
- static void
- current_pane_taller (void)
- { switch (pane)
- { case 3: /* Breakpoint */
- case 4: /* Data */
- if (toplines > 3)
- { toplines--;
- bottomlines++;
- }
- break;
- default:
- if (bottomlines > 1)
- { toplines++;
- bottomlines--;
- }
- break;
- }
- redraw (0);
- }
- /* ---------------------------------------------------------------------- */
- static void
- current_pane_wider (void)
- { switch (pane)
- { case 1: /* Register */
- if (main_x1 > 3)
- main_x1--;
- break;
- case 2: /* Flag */
- break; /* No need to enlarge flag pane */
- case 3: /* Breakpoint */
- if (main_x3 > 11 + 2 * data_dump_size)
- main_x3--;
- break;
- case 4: /* Data */
- if (main_x3 < cols - 4)
- main_x3++;
- break;
- default: /* TopLeftPane*/
- if ((main_x1 < cols - 4) && (main_x2 - main_x1 > 3))
- main_x1++;
- break;
- }
- redraw (0);
- }
- /* ---------------------------------------------------------------------- */
- static char *
- addr_to_str (char *output, word32 addr)
- { char *name;
- int32 delta;
-
- name = syms_val2name (addr, &delta);
- if (name[0] != '0')
- if (delta)
- sprintf (output, "%s+%#lx", name, delta);
- else
- sprintf (output, "%s", name);
- else
- sprintf(output,"0x%08lx",addr);
- return (output);
- }
- /* ---------------------------------------------------------------------- */
- static void
- breakpoint_to_str (char *str, int class, int type, word32 addr,
- int length, int count, char *cond)
- { char temp[200];
-
- sprintf (str, "-class %s -type %s -at %s -length %d ",
- class == 0 ? "normal" : class == 1 ? "count_down" : "conditional",
- type == 0 ? "code" : type == 1 ? "data_write" : "data_read",
- addr_to_str (temp, addr),
- length
- );
- if (class == 1)
- sprintf (str + strlen (str), "-count %d", count);
- if (class == 2)
- sprintf (str + strlen (str), "-condition %s", cond);
- sprintf (str + strlen (str), "%c\n", 0x0d);
- }
- /* ---------------------------------------------------------------------- */
- static PARSE_DEF bp_def[] = {
- {"-class" , STR_TYPE, {0}},
- {"-type" , STR_TYPE, {0}},
- {"-at" , STR_TYPE, {0}},
- {"-length" , INT_TYPE, {0}},
- {"-count" , INT_TYPE, {0}},
- {"-condition", STR_TYPE, {0}},
- {0 , 0 , {0}}
- };
- /* ---------------------------------------------------------------------- */
- static int
- str_to_breakpoint (char *str, int *class, int *type, word32 *addr,
- int *length, int *count, char *cond)
- { int ok;
- char s_class[64], s_type[64], s_addr[128];
-
- s_class[0] = 0; bp_def[0].val.s_val = s_class;
- s_type[0] = 0; bp_def[1].val.s_val = s_type;
- s_addr[0] = 0; bp_def[2].val.s_val = s_addr;
- *length = 4; bp_def[3].val.i_val = length;
- *count = 0; bp_def[4].val.i_val = count;
- cond[0] = 0; bp_def[5].val.s_val = cond;
-
- parse_string (bp_def, str);
- if (stricmp (s_class, "count_down") == 0)
- *class = 1;
- else if (stricmp (s_class, "conditional") == 0)
- *class = 2;
- else
- *class = 0;
- if (stricmp (s_type, "data_write") == 0)
- *type = 1;
- else if (stricmp (s_type, "data_read") == 0)
- *type = 3;
- else
- *type = 0;
- *addr = parse_expression (4, s_addr, &ok);
- if (ok != ParseError_ok)
- ok = 0;
- else
- ok = 1;
- if (*class == 2 && cond[0] == 0)
- ok = 0;
- return (ok);
- }
- /* ---------------------------------------------------------------------- */
- static PARSE_DEF reg_def[] = {
- {"-number" , STR_TYPE, {0}},
- {"-value" , STR_TYPE, {0}},
- {0 , 0 , {0}}
- };
- /* ---------------------------------------------------------------------- */
- static int
- str_to_reg (char *str, char *index, word32 *addr)
- { int ok;
- char s_index[32], s_addr[128];
-
- s_index[0] = 0; reg_def[0].val.s_val = s_index;
- s_addr[0] = 0; reg_def[1].val.s_val = s_addr;
-
- parse_string (reg_def, str);
- if (s_index[0])
- *index = *s_index - '0';
- else
- return (0);
- *addr = parse_expression (4, s_addr, &ok);
- if (ok != ParseError_ok)
- return (0);
- return (1);
- }
- /* ---------------------------------------------------------------------- */
- static PARSE_DEF pa_def[] = {
- {"-start" , STR_TYPE, {0}},
- {"-stop" , STR_TYPE, {0}},
- {0 , 0 , {0}}
- };
- /* ---------------------------------------------------------------------- */
- static int
- str_to_pa (char *str, word32 *addr1, word32 *addr2)
- { int ok;
- char s_start[128], s_stop[128];
-
- s_start[0] = 0; pa_def[0].val.s_val = s_start;
- s_stop[0] = 0; pa_def[1].val.s_val = s_stop;
-
- parse_string (pa_def, str);
- *addr1 = parse_expression (4, s_start, &ok);
- if (ok != ParseError_ok)
- return (0);
- *addr2 = parse_expression (4, s_stop, &ok);
- if (ok != ParseError_ok)
- return (0);
- return (1);
- }
- /* ---------------------------------------------------------------------- */
- static PARSE_DEF pane_def[] = {
- {"-top_lines" , INT_TYPE, {0}},
- {"-top_left_cols", INT_TYPE, {0}},
- {"-top_mid_cols" , INT_TYPE, {0}},
- {"-bot_left_cols", INT_TYPE, {0}},
- {0 , 0 , {0}}
- };
- /* ---------------------------------------------------------------------- */
- static int
- str_to_pane (char *str, int *tl, int *x1, int *x2, int *x3)
- { pane_def[0].val.i_val = tl;
- pane_def[1].val.i_val = x1;
- pane_def[2].val.i_val = x2;
- pane_def[3].val.i_val = x3;
-
- parse_string (pane_def, str);
- return (1);
- }
- /* ---------------------------------------------------------------------- */
- static int
- save_context (int save_bp, int save_reg, int save_pa, int save_pane,
- char *filename)
- { FILE *f;
- int i;
- char temp[200];
-
- f = fopen (filename, "wb");
- if (!f)
- return (0);
- if (save_bp)
- { fputs ("##\015\n", f);
- fputs ("# Breakpoint information\015\n", f);
- fputs ("##\015\n", f);
- fputs (" \015\n", f);
- for (i = 0; i < breakpoint_count; i++)
- { sprintf (read_buffer, "bre ");
- breakpoint_to_str (read_buffer + strlen (read_buffer),
- breakpoint_table[i].sub_type,
- breakpoint_table[i].type,
- breakpoint_table[i].addr,
- breakpoint_table[i].length,
- breakpoint_table[i].count,
- breakpoint_table[i].condition
- );
- fputs (read_buffer, f);
- }
- fputs (" \015\n", f);
- }
- if (save_reg)
- { fputs ("##\015\n", f);
- fputs ("# Debugger registers\015\n", f);
- fputs ("##\015\n", f);
- fputs (" \015\n", f);
- for (i = 0; i < MAX_REGISTERS; i++)
- if (registers[i])
- { sprintf (read_buffer, "reg -number %c -value %s\015\n",
- i + '0',
- addr_to_str (temp, registers[i])
- );
- fputs (read_buffer, f);
- }
- fputs (" \015\n", f);
- }
- if (save_pa)
- { fputs ("##\015\n", f);
- fputs ("# Performance Analyzer\015\n", f);
- fputs ("##\015\n", f);
- fputs (" \015\n", f);
- sprintf (read_buffer, "pa -start %s ",
- addr_to_str (temp, evaluation_data[0].start_addr)
- );
- sprintf (read_buffer + strlen (read_buffer), "-stop %s\015\n",
- addr_to_str (temp, evaluation_data[EVAL_SEGMENTS - 1].stop_addr)
- );
- fputs (read_buffer, f);
- fputs (" \015\n", f);
- }
- if (save_pane)
- { fputs ("##\015\n", f);
- fputs ("# Pane information\015\n", f);
- fputs ("##\015\n", f);
- fputs (" \015\n", f);
- sprintf (read_buffer,
- "pane -top_lines %d -top_left_cols %d -top_mid_cols %d -bot_left_cols %d\015\n",
- toplines, main_x1 - 1, main_x2 - main_x1 - 1, main_x3 - 1
- );
- fputs (read_buffer, f);
- fputs (" \015\n", f);
- }
- fclose (f);
- return (1);
- }
- /* ---------------------------------------------------------------------- */
- static int
- load_context (int load_bp, int load_reg, int load_pa, int load_pane,
- char *filename, int startup_load)
- { FILE *f;
- int err, temp;
- char command[64];
-
- if (startup_load)
- { f = fopen (startup_file, "rb");
- if (!f)
- return (0);
- } else
- { f = fopen (filename, "rb");
- if (!f)
- { message (CL_Error, "Error reading from file %s", filename);
- return (0);
- }
- }
- err = load_bp +
- ((load_reg & 1) << 1) +
- ((load_pa & 1) << 2) +
- ((load_pane & 1) << 3);
- while (fgets (read_buffer, 1024, f))
- { read_buffer[strlen (read_buffer) - 1] = 0;
- if (sscanf (read_buffer, "%s%n", command, &temp) >= 1)
- { if (stricmp (command, "bre") == 0)
- { if (load_bp)
- { int class, type, length, count;
- word32 addr;
- char cond[200];
-
- count = 0;
- cond[0] = 0;
- str_to_breakpoint (read_buffer + temp,
- &class, &type, &addr, &length, &count, cond);
- temp = set_breakpoint (type, length, addr);
- breakpoint_table[temp].sub_type = class;
- breakpoint_table[temp].count = count;
- strcpy (breakpoint_table[temp].condition, cond);
- }
- err &= ~1;
- } else if (stricmp (command, "reg") == 0)
- { if (load_reg)
- { char index;
- word32 addr;
-
- if (str_to_reg ((char *)(read_buffer + temp), &index, &addr))
- { registers[(int)index] = addr;
- err &= ~2;
- }
- }
- } else if (stricmp (command, "pa") == 0)
- { if (load_pa)
- { word32 addr1, addr2;
-
- if (str_to_pa ((char *)(read_buffer + temp), &addr1, &addr2))
- { init_eval_data (addr1, addr2);
- err &= ~4;
- }
- }
- } else if (stricmp (command, "pane") == 0)
- { if (load_pane)
- { int tl = 0, x1 = 0, x2 = 0, x3 = 0;
-
- if (str_to_pane ((char *)(read_buffer + temp), &tl, &x1, &x2, &x3))
- { if (tl < rows - 5 && tl > 3)
- { toplines = tl;
- bottomlines = rows - 4 - toplines;
- }
- if (x1 > 1 && x1 < cols - 5)
- { main_x1 = x1 + 1;
- if (main_x2 - main_x1 < 2)
- main_x2 = main_x1 + 2;
- }
- if (x2 > 0 && main_x1 + x2 < cols - 2)
- main_x2 = main_x1 + x2 + 1;
- if (x3 > 11 + 2 * data_dump_size && main_x3 < cols - 5)
- main_x3 = x3 + 1;
- err &= ~8;
- }
- }
- }
- }
- }
- fclose (f);
- if (startup_load)
- return (1);
- redraw (0);
- if (err)
- message (CL_Error, "File has no %s%s%s%s information",
- err & 1 ? "breakpoints" : "",
- err & 2 ? (err & 1 ? ", registers" : "registers") : "",
- err & 4 ? (err & 3 ? ", P.A. data" : "P.A. data") : "",
- err & 8 ? (err & 7 ? ", pane layouts" : "pane layouts") : "");
- else
- message (CL_Info, "Requested context has been successfully loaded.");
- return (1);
- }
- /* ---------------------------------------------------------------------- */
- static void
- in_ck (char *output, char *input, word32 addr)
- { sprintf (output, "%s", *(int *)addr ? "[X]" : "[ ]");
- }
- /* ---------------------------------------------------------------------- */
- static int
- ed_ck (char *text, word32 addr, int x, int y, int len, int *key)
- { if (*key == K_Return || *key == K_Space)/* Only these keys are accepted */
- { if (*(int *)addr)
- *(int *)addr = 0;
- else
- *(int *)addr = 1;
- }
- *key = 0;
- return 1;
- }
- /* ---------------------------------------------------------------------- */
- static void
- save_load_context (void)
- { int ret = 7;
- static int save_bp = 1, save_reg = 0, save_pa = 0, save_pane = 0;
- static char ct_filename[81];
- static DIALOG_ITEM dialog_data[] = {
- {"Breakpoints :", 0 , 03, 1, format_asis, eval_word, in_ck , ed_ck },
- {"Registers :", 0 , 03, 1, format_asis, eval_word, in_ck , ed_ck },
- {"Performance Analizer :", 0 , 03, 1, format_asis, eval_word, in_ck , ed_ck },
- {"Pane positions :", 0 , 03, 1, format_asis, eval_word, in_ck , ed_ck },
- {"Filename :", 0 , 80, 1, format_asis, eval_asis, init_asis, editor},
- {0 , 0 , 00 ,0, 0 , 0 , 0 , 0 }
- };
- static BUTTON_ITEM button_data[] = {
- {" Save ", 0, action_done},
- {" Load ", 0, action_done},
- {" Cancel ", 0, action_done},
- {0 , 0, 0 }
- };
-
- dialog_data[0].return_addr = (word32)&save_bp;
- dialog_data[1].return_addr = (word32)&save_reg;
- dialog_data[2].return_addr = (word32)&save_pa;
- dialog_data[3].return_addr = (word32)&save_pane;
- dialog_data[4].return_addr = (word32)&ct_filename;
- dialog ("Debugger Context", dialog_data, button_data, &ret);
- switch (ret)
- { case 1:
- if (ct_filename[0])
- if (save_context (save_bp, save_reg, save_pa, save_pane, ct_filename))
- message (CL_Info, "Requested context has been successfully saved.");
- else
- message (CL_Error, "Error writing to file %s", ct_filename);
- break;
- case 2:
- if (ct_filename[0])
- load_context (save_bp, save_reg, save_pa, save_pane, ct_filename, 0);
- break;
- default:
- redraw (0);
- }
- }
- /* ---------------------------------------------------------------------- */
- void
- debugger (void)
- {
- int oldpane, lastpane, bar_select, pop_select, command;
- static void (*keyhandlers[PANECOUNT])(int) =
- {
- &code_pane_command, /* 0 */
- ®ister_pane_command, /* 1 */
- &flag_pane_command, /* 2 */
- &breakpoint_pane_command, /* 3 */
- &data_pane_command, /* 4 */
- &npx_pane_command, /* 5 */
- &stack_pane_command, /* 6 */
- &info_pane_command, /* 7 */
- &whereis_pane_command, /* 8 */
- &module_pane_command, /* 9 */
- &help_pane_command /* 10 */
- };
-
- main_entry = syms_name2val ("_main");
- first_step = !undefined_symbol;
- initialize ();
- if (startup_file[0] != 0)
- if (load_context (1, 1, 1, 1, startup_file, 1))
- message (CL_Info, "Succesfully loaded start-up file %s.", startup_file);
- can_longjmp = 1;
- setjmp (debugger_jmpbuf);
- lastpane = oldpane = -1;
- show_menu_bar (Main_Menu);
- Main_Menu[0].type = 1;
-
- while (1)
- {
- int key;
-
- if (pane < 1 || pane > 4)
- pane = code_pane_active ? 0
- : (npx_pane_active ? 5
- : (stack_pane_active ? 6
- : (info_pane_active ? 7
- : (whereis_pane_active ? 8
- : (module_pane_active ? 9
- : (help_pane_active ? 10
- : (abort (), -1)))))));
- if (pane == oldpane)
- pane_positions[pane] = pane_pos;
- else
- {
- pane_pos = pane_positions[pane];
- lastpane = oldpane;
- oldpane = pane;
- make_pane_name ();
- redraw (0);
- if (whereis_pane_active && !whereis_sym_count)
- init_whereis_sym ();
- }
- escaped = 0;
- control_c = 0;
- control_x = 0;
- switch (key = getykey ())
- { case K_Escape:
- escaped = 1;
- key = getykey ();
- break;
- case K_Control_C:
- control_c = 1;
- key = getykey ();
- break;
- case K_Control_X:
- control_x = 1;
- key = getykey ();
- break;
- }
- command = 0;
- if (escaped)
- switch (key)
- { case K_Escape: /* Esc-Esc */
- pop_select = 0;
- if (!running_xsupport)
- { menu (Main_Menu, &bar_select, &pop_select);
- command = bar_select * 100 + pop_select;
- } else
- { command = 999;
- if (extern_data_support (data_dump_origin +
- pane_positions[DATA_PANE_NUM]))
- { running_xsupport = 0;
- redraw (0);
- }
- }
- break;
- case K_Control_P: /* Esc-^P */
- key = getykey ();
- command = make_pane_from_key (key);
- break;
- default:
- command = 0;
- break;
- }
- if (control_x)
- { command = 999;
- switch (key)
- { case K_Control_C: /* <=> F-Exit */
- if (confirm ("Are you sure (y/n)? "))
- command = 108;
- break;
- case K_Control_V: /* <=> F-Context */
- command = 107;
- break;
- case K_Control_W: /* Write Log */
- log_current_pane ();
- break;
- case K_Control_F: /* Read Log */
- read_log ();
- break;
- case K_Control_E: /* <=> M-Evaluate */
- command = 402;
- break;
- case K_Control_X: /* Prev. Reflexive */
- if ((lastpane >= 0) && (lastpane < PANECOUNT))
- { command = pane;
- pane = lastpane;
- lastpane = command;
- command = 999;
- }
- break;
- case '^': /* Taller */
- current_pane_taller ();
- break;
- case '}': /* Wider */
- current_pane_wider ();
- break;
- case '<': /* Scroll left */
- pane_offset[pane] += SCROLL_COUNT;
- redraw (0);
- break;
- case '>': /* Scroll right */
- if (pane_offset[pane] > 0)
- pane_offset[pane] -= SCROLL_COUNT;
- redraw (0);
- break;
- case 'm': /* Color / Mono */
- case 'M':
- if (screen_attr_normal == screen_attr_asm)
- command = 105;
- else
- command = 104;
- break;
- case 'o':
- case 'O': /* Next pane == Tab */
- control_x = 0;
- key = K_Tab;
- break;
- default:
- command = 0;
- break;
- }
- }
- if (control_c)
- { command = 0; /* No command defined*/
- }
- if (!(escaped || control_x || control_c))
- { command = 999;
- switch (key)
- { case K_Tab:
- if (pane < 1 || pane > 4)
- pane = 1;
- else
- pane++;
- break;
- case K_BackTab:
- if (pane < 1 || pane > 4)
- pane = 4;
- else
- pane--;
- break;
- case K_Control_H: /* Global - Help */
- command = 207;
- break;
- case K_Control_R: /* Global - Run */
- step (2);
- break;
- case K_Control_L: /* Global - Refresh */
- command = 403;
- break;
- case K_Control_Z: /* Global - User Scr*/
- command = 401;
- break;
- default:
- command = 0;
- break;
- }
- }
- switch (command)
- { case 101: /* File - Log */
- switch (pane) /* focused pane */
- { case 1: /* Top middle */
- read_write_log (main_x1 + 1, 2, main_x2, toplines + 1);
- break;
- case 2: /* Top right */
- read_write_log (main_x2 + 1, 2, cols - 1, toplines + 1);
- break;
- case 3: /* Bottom right */
- read_write_log (main_x3+1, toplines+2, cols-1, rows-1);
- break;
- case 4: /* Bottom left */
- read_write_log (1, toplines + 2, main_x3, rows - 1);
- break;
- default: /* Top Left */
- read_write_log (1, 2, main_x1, toplines + 1);
- break;
- }
- break;
- case 102: /* File - Registers */
- view_regs ();
- break;
- case 103: /* File - Resize */
- setup_screen ();
- break;
- case 104: /* File - Mono mode */
- init_color (0);
- oldpane = -1;
- break;
- case 105: /* File - Color */
- init_color (1);
- oldpane = -1;
- break;
- case 106: /* File - Redirect */
- setup_io();
- break;
- case 107: /* File - Context */
- save_load_context ();
- break;
- case 108: /* File - Exit */
- user_screen ();
- can_longjmp = 0;
- if (using_com_port_num)
- com_done();
- if (timer_is_set)
- reset_timer ();
- return;
- case 201: /* Pane - Previous */
- if (pane < 1 || pane > 4)
- pane = 4;
- else
- pane--;
- break;
- case 202: /* Pane - Next */
- if (pane < 1 || pane > 4)
- pane = 1;
- else
- pane++;
- break;
- case 203: /* Pane - Data */
- pane = 3;
- break;
- case 205: /* Pane - Breakpoin*/
- pane = 4;
- break;
- case 206: /* Pane - Flags */
- pane = 2;
- break;
- case 211: /* Pane - Registers*/
- pane = 1;
- break;
- case 204: /* Pane - Code */
- case 207: /* Pane - Help */
- case 208: /* Pane - Info */
- case 209: /* Pane - Module */
- case 210: /* Pane - Npx */
- case 212: /* Pane - Stack */
- case 213: /* Pane - Where-is */
- code_pane_active = (command == 204);
- help_pane_active = (command == 207);
- info_pane_active = (command == 208);
- module_pane_active = (command == 209);
- npx_pane_active = (command == 210);
- stack_pane_active = (command == 212);
- whereis_pane_active = (command == 213);
- pane = 0;
- if (npx_pane_active && !has_npx)
- { message (CL_Error, "NPX not present");
- npx_pane_active = 0;
- code_pane_active = 1;
- }
- break;
- case 214: /* Pane - Resize */
- resize_screen();
- show_menu_bar (Main_Menu);
- oldpane = -1; /* Force redraw. */
- break;
- case 300: /* Local */
- keyhandlers[pane] (0);
- break;
- case 401: /* Misc - User Scre*/
- user_screen ();
- (void) getykey ();
- debug_screen ();
- break;
- case 402: /* Misc - Evaluate */
- { int res, ok;
- res = read_eval (&ok, "");
- if (ok)
- message (CL_Msg, "\"%s\" -> %d (0x%08lx)",
- read_buffer, res, (word32) res);
- break;
- }
- case 403: /* Misc - Refresh */
- re_start_transfer ();
- redraw (0);
- break;
- case 501: /* Help - About */
- message (CL_Info,
- "Ladybug version %d.%02d", MAJOR_VER, MINOR_VER);
- break;
- case 502: /* Help - Help */
- code_pane_active = 0;
- info_pane_active = 0;
- module_pane_active = 0;
- npx_pane_active = 0;
- stack_pane_active = 0;
- whereis_pane_active = 0;
- help_pane_active = 1;
- oldpane = -1; /* Force redraw. */
- break;
- case 999: /* Executed command*/
- break;
- default: /* Not global keys */
- keyhandlers[pane] (key);
- break;
- }
- }
- }
- /* ----------------------------------------------------------------------
- It's a mystery to me --- the game commences
- for the usual fee --- plus expenses
- confidential information --- it's in a diary
- this is my investigation --- it's not a public inquiry
-
- -- Mark Knopfler, "Private Investigations"
- ---------------------------------------------------------------------- */
-